C# 如何确定所有任务何时完成
下面是启动多个任务的示例代码C# 如何确定所有任务何时完成,c#,task-parallel-library,C#,Task Parallel Library,下面是启动多个任务的示例代码 Task.Factory.StartNew(() => { //foreach (KeyValuePair<string, string> entry in dicList) Parallel.ForEach(dicList, entry => { //create and
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(()=>
{
//foreach(dicList中的KeyValuePair条目)
并行。ForEach(dicList,
条目=>
{
//在UI线程中创建并添加进度
var ucProgress=(Progress)fpPanel.Invoke(createProgress,entry);
//在非UI线程中并行执行ucProgress.Process()。
//.Process();必须使用*Invoke更新UI
ucProgress.Process();
系统.线程.线程.自旋等待(5000000);
});
});
.ContinueWith(任务=>
{
//要处理异常,请使用task.Exception成员
var progressBar=(progressBar)task.AsyncState;
如果(!task.IsCancelled)
{
//在此处隐藏进度条并重置pb.Value=0
}
},
TaskScheduler.FromCurrentSynchronizationContext()//从UI线程更新UI
);
当我们使用task.Factory.StartNew()
启动多个任务时,我们可以使用.ContinueWith()
块来确定每个任务何时完成。我的意思是,每完成一项任务,就用一次封锁射击。所以我只想知道TPL库中是否有任何机制。如果我使用task.Factory.StartNew()
启动10个任务,那么我如何在10个任务完成后发出通知。请用示例代码提供一些见解
如果我使用task.Factory.StartNew()启动10个任务,那么在10个任务完成后如何通知
三种选择:
- 阻塞调用,仅在所有给定任务完成时返回
- 异步调用,返回一个任务,该任务在所有给定任务完成时完成。(在.NET 4.5中介绍。)
- ,它添加了一个延续任务,该任务将在所有给定任务完成后运行
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);
Func DummyMethod=()=>{
//准备好后,发送回完成!
返回true;
};
//创建任务列表
System.Threading.Tasks.Task[]Tasks=新系统.Threading.Tasks.Task[2];
//第一项任务
var firstTask=System.Threading.Tasks.Task.Factory.StartNew(()=>DummyMethod(),TaskCreationOptions.LongRunning);
任务[0]=第一个任务;
//第二项任务
var secondTask=System.Threading.Tasks.Task.Factory.StartNew(()=>DummyMethod(),TaskCreationOptions.LongRunning);
任务[1]=第二个任务;
//发射所有
System.Threading.Tasks.Task.WaitAll(任务);
如果我使用task.Factory.StartNew()启动10个任务,那么在10个任务完成后如何通知
你可以用。此调用将阻止当前线程,直到所有任务完成
旁注:您似乎正在使用任务
、并行
和线程.SpinWait
,这使您的代码变得复杂。我会花一点时间分析这种复杂性是否真的必要。另一种解决方案:
在Parallel中的所有操作完成后。对于(…)
它返回一个对象ParallelLoopResult
,:
For返回一个System.Threading.Tasks.ParallelLoopResult对象,当
所有线程都已完成。此返回值在以下情况下非常有用:
手动停止或中断循环迭代,因为
ParallelLoopResult存储上次迭代等信息
完成。如果一个或多个异常发生在
线程,将抛出一个系统。AggregateException
当执行Break()
方法的Stop()
时,类的IsCompleted
属性设置为false
例如:
ParallelLoopResult result = Parallel.For(...);
if (result.IsCompleted)
{
//Start another task
}
请注意,它建议仅在手动断开或停止循环时使用它(否则只需使用
WaitAll
,whalll
等)。它们是否需要一个接一个地运行?没有出现“”。正在此处尝试:Func DummyMethod=()=>{//准备好后,返回complete!返回true;};我认为“Launch all”注释非常混乱,因为WaitAll()
实际上并没有启动任何东西。我正在使用网络版本4.0。我想开始10个任务,我想知道每个任务何时完成,最后一个通知应该在10个任务何时完成。请告诉我你的想法。谢谢TaskFactory.continuewhall(…)
如果你被限制在4.0版也很方便。@KirillShlenskiy:Ooh,很好-错过了,会添加它的。我在4.0版的网络中工作。我想开始10个任务,我想知道每个任务何时完成,最后一个通知应该在10个任务何时完成。请告诉我你的想法。thanks@Thomas:听起来您希望在每个任务上继续执行continuew
,然后调用continuewhalll
以及“一切都已完成”通知。谢谢。你能给我一些提示或者虚拟的示例代码来说明如何将ContinueWhenAll()和ContinueWith()一起使用吗?我现在使用的是网络版本4.0。我想开始10个任务,我想知道每个任务何时完成,最后一个通知应该在10个任务何时完成。请告诉我你的想法。thanks@Thomas我会在每个任务中添加一个.ContinueWith
,以发送作业完成通知,最后一行是task.WaitAll()
。换句话说,每个任务在完成时都通过使用任务链接提供通知,链接的任务只是在完成时报告。还将调用Task.WaitAll
方法-这将允许您发出有关所有任务工作完成的通知。有道理?