0

私は自分が持っている要件を解決する方法を見つけようとしてきましたが、私の人生の間、私は解決策を思い付くことができません。

ある種のキューを格納するアイテムのデータベースがあります。(データベースはすでに実装されており、他のプロセスがこのキューにアイテムを追加します。)

アイテムは「処理」するために多くの作業/時間を必要とするため、次のことができる必要があります。データベースからアイテムを常にデキューします。アイテムごとに、新しいスレッドを実行してアイテムを処理し、正常に処理された場合はtrue/falseを返します。(これは、データベースキューに再追加するかどうかに使用されます)

ただし、これを行うには、現在アクティブなスレッドの数(処理中のアイテムごとに1つ)がスレッドの最大数パラメーターよりも少ない場合に限ります。

スレッドの最大数に達したら、現在のスレッド数が最大スレッド数より少なくなるまで、データベースからのアイテムのデキューを停止する必要があります。その時点で、アイテムのキューからの削除を続行する必要があります。

これは私が思いつくことができるものであるように感じますが、それは私には来ていません。

明確にするために:私はスレッドを実装する必要があるだけです。データベースはすでに実装されています。

4

3 に答える 3

6

これを行う非常に簡単な方法の 1 つは、Semaphore. アイテムをデキューし、それらを処理するスレッドを作成する 1 つのスレッドがあります。例えば:

const int MaxThreads = 4;
Semaphore sem = new Semaphore(MaxThreads, MaxThreads);
while (Queue.HasItems())
{
    sem.WaitOne();
    var item = Queue.Dequeue();
    Threadpool.QueueUserWorkItem(ProcessItem, item); // see below
}
// When the queue is empty, you have to wait for all processing
// threads to complete.
// If you can acquire the semaphore MaxThreads times, all workers are done
int count = 0;
while (count < MaxThreads)
{
    sem.WaitOne();
    ++count;
}

// the code to process an item
void ProcessItem(object item)
{
    // cast the item to whatever type you need,
    // and process it.
    // when done processing, release the semaphore
    sem.Release();
}

上記のテクニックは非常にうまく機能します。コーディングが簡単で、理解しやすく、非常に効果的です。

Task1 つの変更点は、代わりに APIを使用したい場合があることですThreadpool.QueueUserWorkItemTaskキャンセルを含む非同期処理をより詳細に制御できます。QueueUserWorkItem私はそれをよりよく知っているので、私の例で使用しました。Taskプロダクションプログラムで使用します。

これは N+1 スレッド (N は同時に処理する項目の数) を使用しますが、その余分なスレッドは多くの場合、何も実行しません。実行されるのは、作業をワーカー スレッドに割り当てているときだけです。それ以外の場合は、セマフォでビジーでない待機を行っています。

于 2013-03-17T12:28:34.003 に答える
0

どこから始めればよいかわかりませんか?

最大数のスレッドを持つスレッド プールを検討してください。http://msdn.microsoft.com/en-us/library/y5htx827.aspx

最大数のスレッドをすぐにスピンアップし、DB を監視することを検討してください。http://msdn.microsoft.com/en-us/library/system.threading.threadpool.queueuserworkitem.aspxが便利です。

プロセスが安全に終了することを保証できないことに注意してください...クラッシュが発生します。処理状態のロギングを検討してください。

選択操作とキューからの削除操作はアトミックである必要があることに注意してください。

于 2013-03-17T02:22:11.423 に答える