2011-06-30 7 views
2

私のアプリケーションはライブフィードからデータを取得し、一度にライブフィードを1回だけ呼び出すことができます。私は約20のシナリオでforeachを呼び出し、次にこれらのシナリオのそれぞれに対してライブフィードを15回呼び出す必要があります。次のセマフォをリリースするまで、セマフォが解放されないようにする方法は?

私はスレッディングには新しく、インターネットと読書を通してトローリングした後、最終的にセマフォを使用することに決めました。しかし、私は、シナリオのためのライブフィードがその特定のシナリオで15回呼び出されるまで、セマフォー(シナリオの_pool)を待機状態にする方法を見つけることができません。

この問題(私はそこにあると確信しています)より洗練されたソリューションがある場合は、私は感謝します ありがとうございます。今度はいずれか一方のみPを持っているために、1つ以上の追加のスレッド( AT )を生成しますことをプライマリスレッドP)またはいくつかのワーカースレッド(W)のいずれかを有するか、

private void button1_Click(object sender, EventArgs e) 
    { 
     _pool = new Semaphore(0, 1); 
     foreach (string s in str) 
     { 
      Thread n = new Thread(new ParameterizedThreadStart(method1)); 
      n.Start(venue);    
     } 
     _pool.Release(1); 

    } 


    static void method1(object venue) 
    { 
     _pool.WaitOne(); 

     for (int i = 1; i <= numThreads; i++) 
     { 
      string composite = i.ToString() + "," + venue; 
      Thread n = new Thread(new ParameterizedThreadStart(method2)); 
      n.Start(composite); 
     } 
     _pool.Release(); //I need to ensure that this is called only after all threads 
         // spawned in the for loop corresponding to foreach thread are 
         // executed. But how? 
    } 

    static void method2(object i) 
    { 
     _pool2.WaitOne(); 

     //Call to data engine and storing data in txt file 

     Thread.Sleep(100); 

     _pool2.Release(); 


    } 
+0

興味深い質問ですが、当初私はそれらのマシュマロクッキーのことを考えていましたが、 – heisenberg

+1

間違った同期オブジェクト、セマフォーは間違った方法を数えています。必要なのは、すべてのスレッドでThread.Join()です。または、スレッドによってSet()であるAutoResetEventのWaitAll()。 –

答えて

0

Wすべてが完了するまでスレッドを使用しないでください。 Pがとにかく ATが完了するまでブロックされているので、シナリオPにあなたにも直接法2()を呼び出すことができます。状況はWと同じことが言えます。

WaitAll()またはイベントに待ってブロックし、発信者を強制するので、おそらく別の方法が、同じように悪いです。そのようなパターンはうまくスケールされず、何か他のことをしているときにスレッドを無駄にする。

代替は、メインスレッド(または親)各スレッドの終了を警告する非同期通知またはスレッドマーシャリングを使用することです。アプリケーションがGUIであるため、.NETのControl.Invoke()またはControl.BeginInvoke()を使用することができます。 myForm.BeginInvoke(...)myFormのメソッドを警告するには、単にスレッドが終了し、他の中間スレッドWではなく新しいタスク管理がすべて処理されていることを通知するだけです。

を呼び出し()とBeginInvokeをの間にいくつかの重要な違いがあります()。 呼び出し()ブロック呼び出しがUIスレッドにマーシャリングされ、後者が完了するまで戻りません。この場合、それを使用するのは良い考えではないでしょう。

はBeginInvokeメソッド()Windowsのメッセージポンプを経由して非同期にUIスレッドでメソッドを呼び出します。あなたのワーカースレッドはではなく、がブロックされています。これが最良の選択です。

関連する問題