这是启动多个任务的示例代码
Task.Factory.StartNew(() =>
{
//foreach (KeyValuePair<string, string> entry in dicList)
Parallel.ForEach(dicList,
entry =>
{
//create and add the Progress in UI thread
var ucProgress = (Progress)fpPanel.Invoke(createProgress, entry);
//execute ucProgress.Process(); in non-UI thread in parallel.
//the .Process(); must update UI by using *Invoke
ucProgress.Process();
System.Threading.Thread.SpinWait(5000000);
});
});
.ContinueWith(task =>
{
//to handle exceptions use task.Exception member
var progressBar = (ProgressBar)task.AsyncState;
if (!task.IsCancelled)
{
//hide progress bar here and reset pb.Value = 0
}
},
TaskScheduler.FromCurrentSynchronizationContext() //update UI from UI thread
);
当我们使用Task.Factory.StartNew()
启动多个任务时,我们可以使用.ContinueWith()
块来确定每个任务何时完成。我的意思是每次任务完成后,ContinueWith会阻止一次。所以我只想知道TPL库中是否有任何机制。如果我使用Task.Factory.StartNew()
启动10个任务,那么在10个任务完成后如何通知我。请提供示例代码的一些见解。
答案 0 :(得分:23)
如果我使用Task.Factory.StartNew()启动10个任务,那么如何在10个任务完成后通知
三个选项:
Task.WaitAll
调用,仅在所有给定任务完成后才返回Task.WhenAll
调用,它返回一个任务,该任务在所有给定任务完成时完成。 (在.NET 4.5中引入。)TaskFactory.ContinueWhenAll
,它添加了一个继续任务,该任务将在所有给定任务完成后运行。答案 1 :(得分:2)
您可以使用WaitAll()。示例:
Func<bool> DummyMethod = () =>{
// When ready, send back complete!
return true;
};
// Create list of tasks
System.Threading.Tasks.Task<bool>[] tasks = new System.Threading.Tasks.Task<bool>[2];
// First task
var firstTask = System.Threading.Tasks.Task.Factory.StartNew(() => DummyMethod(), TaskCreationOptions.LongRunning);
tasks[0] = firstTask;
// Second task
var secondTask = System.Threading.Tasks.Task.Factory.StartNew(() => DummyMethod(), TaskCreationOptions.LongRunning);
tasks[1] = secondTask;
// Launch all
System.Threading.Tasks.Task.WaitAll(tasks);
答案 2 :(得分:2)
如果我使用Task.Factory.StartNew()启动10个任务,那么如何在10个任务完成后通知
您可以使用Task.WaitAll。此调用将阻止当前线程,直到所有任务完成。
旁注:您似乎正在使用Task
,Parallel
和Thread.SpinWait
,这会使您的代码变得复杂。我会花一点时间分析是否真的有必要进行复杂化。
答案 3 :(得分:0)
另一种解决方案:
完成Parallel.For(...)
内部的所有操作后,它返回ParallelLoopResult
,Documentation的对象:
For在以下情况下返回 System.Threading.Tasks.ParallelLoopResult 对象 所有线程均已完成。当您处于以下状态时,此返回值很有用 手动停止或中断循环迭代,因为 ParallelLoopResult 存储诸如上一次迭代之类的信息 跑完了。如果其中一个发生一个或多个例外 线程,将抛出 System.AggregateException 。
ParallelLoopResult
类具有IsCompleted
属性,当执行Stop()
方法中的Break()
时,该属性设置为false。
示例:
ParallelLoopResult result = Parallel.For(...);
if (result.IsCompleted)
{
//Start another task
}
请注意,建议仅在手动中断或停止循环时使用它(否则,只需使用WaitAll
,WhenAll
等)。