2011-11-17 15 views
8

私はサマリーエントリでいっぱいのデータテーブルを持っており、詳細を取得するために私のソフトウェアにアクセスしてウェブサービスに連絡し、それらの詳細をデータベースに記録し直す必要があります。 Webサービスを呼び出して応答を待っている間にテーブルを同期してループするのは遅すぎるので(何千ものエントリがあるので)、結果(10回程度)を取り出してスレッドを実行して10同時に操作します。データベースキューに対してスレッドプールを管理する最善の方法

C#スレッドでの私の経験は、最低限に抑えられているので、最適なアプローチは何ですか? .NETには、結果が正しく処理されるかどうかを確認するために使用できるスレッドセーフなキューシステムがありますか?

+2

.Netのどのバージョンをお使いですか? .Net 4のマルチスレッドプログラミングには大きな改善があります。 – svick

+0

これを含めるべきです..現在3.5をターゲットにしていますが、私は大きな問題なく4.0に行くことができます。 –

答えて

5

.NET Frameworkのバージョンに応じて、2つのかなり良いオプションがあります。

ThreadPool.QueueUserWorkItemはどのバージョンでも使用できます。

int pending = table.Rows.Count; 
var finished = new ManualResetEvent(false); 
foreach (DataRow row in table.Rows) 
{ 
    DataRow capture = row; // Required to close over the loop variable correctly. 
    ThreadPool.QueueUserWorkItem(
    (state) => 
    { 
     try 
     { 
     ProcessDataRow(capture); 
     } 
     finally 
     { 
     if (Interlocked.Decrement(ref pending) == 0) 
     { 
      finished.Set(); // Signal completion of all work items. 
     } 
     } 
    }, null); 
} 
finished.WaitOne(); // Wait for all work items to complete. 

.NET Framework 4.0を使用している場合は、Task Parallel Libraryを使用できます。

var tasks = new List<Task>(); 
foreach (DataRow row in table.Rows) 
{ 
    DataRow capture = row; // Required to close over the loop variable correctly. 
    tasks.Add(
    Task.Factory.StartNew(
    () => 
     { 
     ProcessDataRow(capture);   
     })); 
} 
Task.WaitAll(tasks.ToArray()); // Wait for all work items to complete. 

これには他にも多くの方法があります。上記のパターンは、簡単であり、うまく機能するため、強調しています。具体的な詳細がない場合は、いずれかがあなたの状況に完全にマッチするとは言えませんが、それは良い出発点になるはずです。

更新:

私は基準以下の脳活動の短い期間を持っていました。あなたがTPLを利用できるなら、Task hocus-pocusよりも簡単な方法としてParallel.ForEachを使うこともできます。

Parallel.ForEach(table.Rows, 
    (DataRow row) => 
    { 
    ProcessDataRow(row); 
    }); 
+0

ところで、Reactive ExtensionsバックポートをMicrosoftのWebサイトからダウンロードした場合、3.5でTPLを実際に使用することができます。 –

+0

素晴らしいもの - 多くの皆様に感謝します。この猫をスキンするいくつかの方法があるように見えます! –

+0

ちょうど1つのこと(そして私は知っている、私はRTFMに行くよ!)しかし、どのようにこのスケールですか?私は何千もの行をやっているので、何千ものスレッドを並行して起動したくはありません。私は(期待している?)何らかの種類の制限が組み込まれているので、ユーザーのコンピュータが停止することはありません。 –

5

.NETには、結果が正しく処理されるかどうかを確認するために使用できるスレッドセーフキューシステムがありますか?

これは.NET 4で追加されたものです。BlockingCollection<T>クラスは、デフォルトでプロデューサ/コンシューマシナリオのスレッドセーフキューとして機能します。

1つ以上の要素をコレクションに追加して、コレクションとプロセスから「消費する」要素を作成するのはかなり簡単です。

+0

非常にいいです、私は間違いなくそれをチェックアウトします。ありがとう! –

+0

並行キューはどうですか? http://msdn.microsoft.com/en-us/library/dd267265.aspx? – Dykam

+0

@Dykam 'BlockingCollection 'は、デフォルトで 'ConcurrentQueue 'をラップします。 CQを直接使用することはできますが、前述のようにプロデューサ/コンシューマのシナリオで作業したい場合、BCはこれをかなり簡単にします。 –

関連する問題