2011-06-30 90 views
2

我的應用程序從實時供稿中提取數據,並且一次只能對實時供稿進行一次調用。我爲約20個場景調用foreach,然後爲每個場景調用15次實時饋送。如何確保信號量在我釋放隨後的信號之前不會釋放?

我是一個新的線程,並通過互聯網和閱讀拖網後,我終於決定使用信號量。但是,我無法找到一種方法來首先保持信號量(用於場景的_pool),直到爲特定場景調用15次實時饋送。

我希望如果有一個更優雅的解決方案,這個問題(我敢肯定有這個問題) 在此先感謝。具有

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

+1一個有趣的問題,雖然我最初是想着那些棉花糖餅乾的東西 – heisenberg

+1

錯誤的同步對象,信號量計數錯誤的方式。所有你需要的是所有線程上的Thread.Join()。或者由線程設置()的AutoResetEvent上的WaitAll()。 –

回答

0

主線程P)或某些工作線程(W¯¯),然後再將派生的一個或多個額外的線程(AT)只要具有任一PW等到全部AT完成並不是最好的線程使用。在場景P你可能會調用方法2()直接自P被阻止,直到AT無論如何完成。對於情況W也是如此。

爲WaitAll()或等待一個事件是另一種方式,但同樣糟糕也許是因爲它迫使調用者阻塞。這樣的模式不能很好地擴展並且在可能做其他事情時浪費了一個線程。

一個替代方案是使用異步通知螺紋編組以提醒主線程(或父)每個線程退出時。因爲你的應用程序是一個GUI,你可以利用.NET的Control.Invoke()或Control.BeginInvoke()。從你的工作線程,只需撥打myForm.BeginInvoke(...)在myForm的提醒的方法,你的線程剛剛退出,並擁有所有新的任務管理處理存在,而不是在其他一些中間線W¯¯

Invoke()和BeginInvoke()之間存在一些重要差異。 調用()工作線程,而調用編組到UI線程,並不會返回,直到後者完成。所以在這種情況下使用它可能不是一個好主意。

的BeginInvoke()調用在經由視窗消息泵異步UI線程的方法。你的工作者線程是而不是被阻止。這是最好的選擇。

相關問題