所有线程完成执行后如何显示消息框?

时间:2014-01-22 15:20:54

标签: c# .net c#-4.0 data-structures

想要使用线程分解一个非常繁重的函数,并在工作完成时显示一个消息框。

以下是类似的代码:

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

想要在所有这些线程完成执行并完成整个工作后显示一个消息框。我该怎么做? 加入将无法正常工作,因为它会导致不使用线程。

3 个答案:

答案 0 :(得分:7)

如果你在.Net4.0 +中,请扔掉旧学校的主题。使用Task paralell库。

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

使用ContinueWhenAll异步等待,并使用FromCurrentSynchronizationContext在UIThread中执行回调。

答案 1 :(得分: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 ...

,它将导致循环永远运行

答案 2 :(得分:1)

为什么你不使用Parallel.Foreach()代替它,它会自动等待所有。像这样:

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