任务链接(等待上一个任务完成)

问题描述:

var tasks = new List<Task>(); 

foreach (var guid in guids) 
{ 
    var task = new Task(...); 
    tasks.Add(task); 
} 

foreach (var task in tasks) 
{ 
    task.Start(); 
    Task.WaitAll(task); 
} 

这是UI线程的运行。我需要一个接一个地执行任务中的所有任务变量。问题是如果我调用Task.WaitAll(任务),UI冻结。如何在不冻结UI的情况下执行以下逻辑?任务链接(等待上一个任务完成)

+4

那你为什么不做一个大的代表呢? – SLaks 2012-07-25 12:26:40

+0

要添加到@SLaks所说的内容中,如果您只有一个要运行的内容列表,那么使用类似BackgroundWorker的内容可能会更简单。真正的未知是你在后台工作完成时想要发生的事情 - 假设它是某种UI更新,BackgroundWorker已经通过在UI线程上运行完成的委托来处理它。 – 2012-07-25 16:24:06

这不是任务链接。

您需要使用ContinueWith来完成任务链接。上一个任务需要更新UI。

Task.Factory.StartNew(() => DoThis()) 
    .ContinueWith((t1) => DoThat()) 
    .ContinueWith((t2) => UpdateUi(), 
     TaskScheduler.FromCurrentSynchronizationContext()); 

注意最后有TaskScheduler.FromCurrentSynchronizationContext()这将确保任务将在同步上下文(UI线程)运行。

您需要使用continutations:

lastTask.ContinueWith(() => newTask.Start()); 

最好的方法是使用任务并行库(TPL)继续。延续不仅可以让您创建任务流程,还可以处理您的例外情况。这是TPL的great introduction。但是,为了给你一些想法...

可以使用

Task task = Task.Factory.StartNew(() => 
{ 
    // Do some work here... 
}); 

现在开始第二个任务时的先行任务结束(错误或成功),你可以使用ContinueWith方法开始TPL任务

Task task1 = Task.Factory.StartNew(() => Console.WriteLine("Antecedant Task")); 
Task task2 = task1.ContinueWith(antTask => Console.WriteLine("Continuation...")); 

因此,一旦task1完成,失败或取消task2“火机”,开始运行。请注意,如果task1已经在达到第二行代码task2之前完成,那么计划立即执行。传递给第二个lambda的参数antTask是对先行任务的引用。见this link更详细的例子...

您也可以从先行任务

Task.Factory.StartNew<int>(() => 1) 
    .ContinueWith(antTask => antTask.Result * 4) 
    .ContinueWith(antTask => antTask.Result * 4) 
    .ContinueWith(antTask =>Console.WriteLine(antTask.Result * 4)); // Prints 64. 

记妙传延续的结果。请务必阅读提供的第一个链接中的异常处理,因为这会导致TPL的新手入歧途。

最后要特别注意的是你想要的是儿童任务。子任务是那些被创建为AttachedToParent的任务。在这种情况下,继续将不运行,直到所有子任务完成

TaskCreationOptions atp = TaskCreationOptions.AttachedToParent; 
Task.Factory.StartNew(() => 
{ 
    Task.Factory.StartNew(() => { SomeMethod() }, atp); 
    Task.Factory.StartNew(() => { SomeOtherMethod() }, atp); 
}).ContinueWith(cont => { Console.WriteLine("Finished!") }); 

我希望这有助于。