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中介绍。)
  • ,它添加了一个延续任务,该任务将在所有给定任务完成后运行
您可以使用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);
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
方法-这将允许您发出有关所有任务工作完成的通知。有道理?