任务继续奇怪的行为

时间:2013-08-03 14:08:13

标签: c# task-parallel-library

我使用条件延续构建了一小组任务,但是我遇到了一些令人厌烦的行为。 我的链看起来像这样:

LoadSettings (OnlyOnFaulted)-> ErrorHandler (none)-> Cleanup (none)-> Exit  
| (OnlyOnRanToCompletion)  
CheckForUpdates (OnlyOnFaulted)-> ErrorHandler (none)-> Cleanup (none)-> Exit  
| (OnlyOnRanToCompletion)  
Update (OnlyOnFaulted)-> ErrorHandler (none)-> Cleanup (none)-> Exit  
| (OnlyOnRanToCompletion)   
Cleanup  (OnlyOnFaulted)-> ErrorHandler (none)-> Exit  
| (OnlyOnRanToCompletion)   
Exit

据我所知,这个链应该异步运行(即不在ui线程中)但是一个接一个地运行(所以LoadSettings - > CheckForUpdates - > ...)。 但是我得到这种行为:
LoadSettings - > CheckForUpdates - >清理 - >退出 - >清理 - > ... 此外,第一个Cleanup以Task id 1作为参数调用(这是之前执行的任务,对吗?),此Task的状态为Canceled(我从不在任何地方取消任务)。
有谁知道这里出了什么问题?

编辑:好的,根据msdn,如果没有达到延续的条件,它的任务就会被取消。因此,ErrorHandler被取消了,但是如何停止整个链(或通过清理通知其他连续并退出它已被取消)?

2 个答案:

答案 0 :(得分:0)

使用Task.WhenAny,您可以创建在成功处理程序或错误处理程序完成时运行的任务。关闭该任务后,您继续Cleanup

设置正确的连续链有时很棘手,但你可以使用像Task.WhenAny这样的组合函数构建非常复杂的流程图。

如果你可以使用async / await这个任务简化了很多。然后,您可以使用常规控制流构造。您还可以使用迭代器模拟等待。

答案 1 :(得分:0)

设置ErrorHandler - >清理继续,因为OnlyOnRanToCompletion或NotOnCanceled可以工作。此外,也许你可以用异步简化一些事情。这样的事情可以奏效:

try {
    var settings = await LoadSettings();
    var updatesNeeded = await CheckForUpdates(settings);
    await Update(updatesNeeded);
} catch (Exception e) {
    ErrorHandler(e);
} finally {
    Cleanup();
}

请注意,错误处理和清理在这里是同步的,因为您无法在catch / finally块中等待。您可以通过仅将异常存储在变量中来解决这个问题,稍后您将检查该变量并将其传递给异步错误处理程序。