2014-01-22 38 views
1

想要使用線程分解非常繁重的函數,並在工作完成時顯示消息框。如何在所有線程完成執行後顯示消息框?

下面是類似的代碼:

for (int index = 0; index < tests.Count; index/=3) 
{ 
    System.Threading.Thread t = 
     new System.Threading.Thread(
      () => SomeFunction(tests.GetRange(start, 3))); 
    t.Start(); 
} 

要一次顯示一個消息框,所有這些線程都完成執行,整個工作完成。我該怎麼做? 加入將無法正常工作,因爲它會在不使用線程的同時發生。

+0

你知道Parallel.For'的'用的描述在這裏http://msdn.microsoft.com/en-us/library/system.threading.tasks.parallel.for%28v= vs.100%29.aspx – Scoregraphic

+1

你知道你的循環總是會執行一次,最多是正確的嗎? –

+0

@CareyGregory,不,它會永遠執行,除非'tests.Count == 0' –

回答

3

如果使用任務,而不是線程它更容易:

var tasks = new List<Task>(); 
for (int index = 0; index < tests.Count; index/=3) 
{ 
    var task = Task.Factory.StartNew(() => SomeFunction(tests.GetRange(start, 3))); 
    tasks.Add(tasks); 
} 

Task.WaitAll(tasks.ToArray()); 
MessageBox.Show("Done!"); 

如果你真的想使用線程,一個選擇是使用等待句柄:

var waitHandles = new List<EventWaitHandle>(); 
for (int index = 0; index < tests.Count; index/=3) 
{ 
    var waitHandle = new ManualResetEvent(false); 
    waitHandles.Add(waitHandle); 
    System.Threading.Thread t = 
     new System.Threading.Thread(
      () => 
      { 
       SomeFunction(tests.GetRange(start, 3)); 
       waitHandle.Set(); 
      }); 
    t.Start(); 
} 
WaitHandle.WaitAll(waitHandles.ToArray()); 
MessageBox.Show("Done!"); 

請注意,如果你把這個在UI線程上,UI將被凍結,直到所有線程完成。如果你想避免這種情況,更好的選擇是使用Task.Factory.ContinueWhenAll,正如Sriram Sakthivel的回答中所建議的那樣。

順便說一句,你確定index/=3部分?這將導致循環運行,如果test.Count > 0 ...

+0

如果這是從UI線程調用'WaitAll'不是正確的選擇 –

+0

@SriramSakthivel,好點。我更新了我的答案,提到了這一點,並提到了你的答案。 –

6

如果你在.Net4.0 +扔掉舊學校的線程。使用任務並行庫。

var uiContext = TaskScheduler.FromCurrentSynchronizationContext(); 
var tasks = ...;//Start tasks 
Task.Factory.ContinueWhenAll(tasks, antecedents => 
{ 
    //Show messagebox here 
},CancellationToken.None,TaskContinuationOptions.None,uiContext); 

等待異步使用ContinueWhenAll和執行使用FromCurrentSynchronizationContext在UIThread回調。

+0

在for循環中: var task = System.Threading.Tasks.Task.Factory.StartNew(()=> SomeFunction(cnt,tests.GetRange(start,3))); tasks.Add(task); 然後: System.Threading.Tasks.Task.Factory.ContinueWhenAll(tasks.ToArray(),前提=> {// 消息框,顯示這裏 如果(定時器= NULL) timer.Stop(); MessageBox.Show(timer.ElapsedMilliseconds.ToString()); }); 但某種程度上Somefunction()沒有得到執行 – priyam

+0

調試並查看是否執行循環,如果是在'SomeFunction'中添加一個消息框並查看是否執行 –

1

爲什麼你不使用Parallel.Foreach()而是它會自動等待所有。事情是這樣的:

Parallel.ForEach(Enumerable.Range(1, 10), i => 
{ 
    Console.WriteLine("{0} - {1}", i, GetTotal()); 
}); 
+3

是的,除了它只支持循環變量的線性增量(ie'i ++')... OP使用'index/= 3'(這沒有多大意義IMO)。 –

相關問題