C# 如何在所有线程完成执行后显示消息框?
希望使用线程分解一个非常繁重的函数,并在工作完成时显示一个消息框 以下是类似代码:C# 如何在所有线程完成执行后显示消息框?,c#,.net,c#-4.0,data-structures,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(); } for
for (int index = 0; index < tests.Count; index/=3)
{
System.Threading.Thread t =
new System.Threading.Thread(
() => SomeFunction(tests.GetRange(start, 3)));
t.Start();
}
for(int index=0;indexSomeFunction(tests.GetRange(start,3));
t、 Start();
}
希望在所有这些线程完成执行并完成整个工作后显示一个消息框。我该怎么做?
Join将无法工作,因为它将导致与不使用线程相同的时间。如果使用任务而不是线程,则更容易:
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 tasks=newlist();
对于(int index=0;indexSomeFunction(tests.GetRange(start,3));
任务。添加(任务);
}
Task.WaitAll(tasks.ToArray());
MessageBox.Show(“完成!”);
如果确实要使用线程,可以选择使用等待句柄:
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!");
var waitHandles=new List();
对于(int index=0;index
{
SomeFunction(tests.GetRange(start,3));
waitHandle.Set();
});
t、 Start();
}
WaitHandle.WaitAll(waitHandles.ToArray());
MessageBox.Show(“完成!”);
请注意,如果在UI线程上调用此函数,UI将被冻结,直到所有线程完成。如果您想避免这种情况,更好的选择是使用Task.Factory.continuewheall
,正如斯里拉姆·萨基维尔的回答中所建议的那样
顺便问一下,你确定
索引/=3
部分吗?如果test.Count>0
…使用任务而不是线程,则会导致循环永远运行:
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 tasks=newlist();
对于(int index=0;indexSomeFunction(tests.GetRange(start,3));
任务。添加(任务);
}
Task.WaitAll(tasks.ToArray());
MessageBox.Show(“完成!”);
如果确实要使用线程,可以选择使用等待句柄:
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!");
var waitHandles=new List();
对于(int index=0;index
{
SomeFunction(tests.GetRange(start,3));
waitHandle.Set();
});
t、 Start();
}
WaitHandle.WaitAll(waitHandles.ToArray());
MessageBox.Show(“完成!”);
请注意,如果在UI线程上调用此函数,UI将被冻结,直到所有线程完成。如果您想避免这种情况,更好的选择是使用Task.Factory.continuewheall
,正如斯里拉姆·萨基维尔的回答中所建议的那样
顺便问一下,你确定
索引/=3
部分吗?如果test.Count>0
..使用.Net4.0+,它将导致循环永远运行。使用任务并行库
var uiContext = TaskScheduler.FromCurrentSynchronizationContext();
var tasks = ...;//Start tasks
Task.Factory.ContinueWhenAll(tasks, antecedents =>
{
//Show messagebox here
},CancellationToken.None,TaskContinuationOptions.None,uiContext);
使用
continuewheall
异步等待,并使用FromCurrentSynchronizationContext
在UIThread中执行回调。如果使用.Net4.0+,请扔掉旧的线程。使用任务并行库
var uiContext = TaskScheduler.FromCurrentSynchronizationContext();
var tasks = ...;//Start tasks
Task.Factory.ContinueWhenAll(tasks, antecedents =>
{
//Show messagebox here
},CancellationToken.None,TaskContinuationOptions.None,uiContext);
使用
continuewheall
异步等待,并使用CurrentSynchronizationContext中的执行UIThread中的回调。为什么不改用Parallel.Foreach()
,它将自动等待所有。大概是这样的:
Parallel.ForEach(Enumerable.Range(1, 10), i =>
{
Console.WriteLine("{0} - {1}", i, GetTotal());
});
为什么不改为使用Parallel.Foreach()
,它将自动等待所有。大概是这样的:
Parallel.ForEach(Enumerable.Range(1, 10), i =>
{
Console.WriteLine("{0} - {1}", i, GetTotal());
});
你知道并行的吗?对于这里的描述,你知道你的循环最多只执行一次,对吧?@CareyGregory,不,它将永远执行,除非tests.Count==0
@thomaslevoops,我的错。你是对的。你知道并行吗。对于这里的描述,你确实意识到你的循环将始终执行一次,最多一次,对吗?@CareyGregory,不,它将永远执行,除非tests.Count==0
@thomaslevsque Oops,我的错。没错。是的,只是它只支持循环变量的线性递增(即i++
)。。。OP使用index/=3
(这在我看来没有多大意义)。是的,除了它只支持循环变量的线性递增(即i++
)。。。OP使用index/=3
(这在我看来没有多大意义)。如果从UI线程调用它,则WaitAll
是不正确的choice@SriramSakthivel,说得好。我更新了我的答案,提到了这一点,并参考了你的答案。如果这是从UI调用,线程WaitAll
是不对的choice@SriramSakthivel,说得好。我更新了我的答案以提及这一点,并参考了您的答案。在for循环中:var task=System.Threading.Tasks.task.Factory.StartNew(()=>SomeFunction(cnt,tests.GetRange(start,3));任务。添加(任务);然后:System.Threading.Tasks.Task.Factory.continuewhell(Tasks.ToArray(),antecedents=>{//Show messagebox here if(timer!=null)timer.Stop();messagebox.Show(timer.elapsedmillesons.ToString();});但是,不知何故,Somefunction()没有执行调试并查看是否执行了循环,如果是,则在Somefunction
中添加一个消息框,并查看是否在for循环中执行:var task=System.Threading.Tasks.task.Factory.StartNew(()=>Somefunction(cnt,tests.GetRange(start,3));任务。添加(任务);然后:System.Threading.Tasks.Task.Factory.continuewhell所有(Tasks.ToArray(),antecedents=>{//Show messageb