質問

私はスレッドを初めて使用するので助けが必要です。新しいレコードを挿入するのに非常に長い時間 (つまり 50 ~ 75 秒) かかるデータ入力アプリがあります。したがって、私の解決策は、ThreadPool 経由で挿入ステートメントを送信し、挿入の実行中に新しいレコード ID を返す挿入中にユーザーがレコードのデータの入力を開始できるようにすることでした。私の問題は、その挿入から新しい ID が返される前にユーザーが保存を押すことができることです。

安全に保存できる場合、そのスレッドからのイベントを介して true に設定されるブール変数を入れてみました。それから私は入れました

while (safeToSave == false)  
{  
    Thread.Sleep(200)  
}  

それは悪い考えだと思います。トレッドが戻る前に save メソッドを実行すると、スタックしてしまいます。

そこで私の質問は次のとおりです。

  1. これを行うより良い方法はありますか?
  2. ここで私は何を間違っているのでしょうか?

助けていただきありがとうございます。
ダグ

詳細については編集してください:

非常に大きな (最大サイズに近づいている) FoxPro データベースへの挿入を実行しています。このファイルには約 200 のフィールドとほぼ同数のインデックスがあります。
質問する前に言っておきますが、私がいる前からここにあり、大量のレガシーコードがヒットしているため、その構造を変更することはできません。最初の問題は、新しい ID を取得するには、まずテーブル内の max(id) を見つけてから、それをインクリメントしてチェックサムする必要があることです。これには約 45 秒かかります。次に、最初の挿入は単純に、その新しい ID と enterdate フィールドを挿入します。このテーブルは DBC に入れられません/入れられないため、自動生成 ID などは除外されます。

@joshua.ewer
あなたは正しいプロセスを持っているので、短期的には保存ボタンを無効にするだけだと思いますが、それをキューに渡すというあなたのアイデアを検討します。参照すべき MSMQ に関するリファレンスはありますか?

役に立ちましたか?

解決

あなたを含む他の人は中心的な問題 (挿入時間、挿入を行う理由、その後更新) に対処したため、私はあなたが提案した解決策に関する技術的な懸念点だけに留めておきます。したがって、流れを正しく理解すると、次のようになります。

  • スレッド 1:レコードのデータ入力を開始します

  • スレッド 2:新しい ID を取得するための DB へのバックグラウンド呼び出し

  • 保存ボタンは常に有効になります。ユーザーがスレッド2が完了する前に保存しようとすると、#1を200ミリ秒間スリープしますか?

最善ではないが最も単純な答えは、ボタンを無効にし、そのスレッドで 折り返し電話 ボタンを有効にするデリゲートに送信します。適切に設定されていることを確認するまで、更新操作を開始することはできません。

ただし、より良い解決策は (FoxPro への Q&D フロントエンドを構築しているだけなら大げさかもしれませんが)、これらの保存操作をキューに投入することだと思います。ユーザーはできるだけ早くキーを入力すると、リクエストが MSMQ などに入れられ、非同期で独自の時間内に完了できます。

他のヒント

1)多くの:)、例えばあなたは、スレッドがオブジェクトを挿入している間に、「保存」ボタンを無効にすることができ、またはあなたがセットアップ「の要求を保存」のキューを扱うスレッド労働者は(私はここでの問題を考えることができます)多分それは良いでしょう、ユーザーが新たに作成されたレコードを変更したいということですので、ボタンを無効にする

2)私は

)...私たちが理解できるようにするには、いくつかのより多くのコードが必要だと思う(または多分同期の問題で、私もスレッドのバグのファンではありません インサートは、あなたが最初にそのコードをチェックすべきだと思うlong..Iので、取るべき理由

ところで、私は理解していません! < - チャールズは前に述べたと同じように(申し訳ありませんが、記事を読んdind't):)

将来を使用するむしろ、生のThreadPoolのアクションよりも。未来を実行し、将来の値を要求し、彼らは第二レコードで保存を打ったときに、ユーザは、彼らが望むものは何でもすることができます。第一のインサートがすでに終了している場合は、すぐにIDを取得しますし、第二のインサートをキックオフすることが許可されます。あなたはまだ第一操作で待機している場合は、それが利用可能になるまで、将来はブロックされ、その後、第二の操作が実行できます。

ユーザーが操作よりも遅くなる場合を除き、

あなたは、任意の時間を節約していない。

まず、あなたはおそらく、インサートが、そう長く取っている理由を知る、そして修正する必要があります... 50〜75秒は、単一の行の挿入のための現代の任意のデータベースのための無理がある、と何か他のものがあることが必要であることを示していますインデックスのように、対処、またはブロッキング...

あなたはデータを持って前に

第二に、なぜあなたは、レコードを挿入していますか?通常、データ入力アプリケーションは、挿入のために必要なすべてのデータがユーザーから収集されるまでの挿入が試行されないようにコード化されています。後でユーザーが入力したデータを使用して新しい空のレコードを最初に戻って、データベースから新しいIDを取得しようとしているので、これを実行した後、「更新」していますか?そうであれば、ほぼすべてのデータベース・ベンダーは、新しいIDを知らなくても、一度だけ挿入を行うと、データベースが同様に新しいIDを返すことができますメカニズムを持っている...あなたはどのようなベンダーのデータベースを使用していますか?

このような可能なソリューションです。

ユーザーも追加して開始する前に、

固有のIDを事前に計算します。テーブルに既にあるが、保有者を効果的に配置されているユニークなIDのリストを保管してください。ユーザーが挿入しようとした場合、ユーザーを押すが、保存するときに、彼らは今、自分のデータでプレースホルダを置き換え、それらにユニークなIDのいずれかを予約します。

PS:それはこれを確認することは困難ですが、あなたが(またはスレッドなし)を提案しているもので、次の同時実行の問題に注意してください:ユーザーAは、追加するために開始し、ユーザーBが追加を開始し、利用者Aは、AS ID 1234を算出し、最大の無料IDは、ユーザーBが最大の無料IDとしてID 1234を計算します。ユーザーAはID 1234を挿入し、ユーザBはID 1234を挿入=ブーム!

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top