1

我建立了一个带有条件延续的小任务链,但是我遇到了一些奇怪的行为。我的链看起来像这样:

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 -> Exit -> Cleanup -> ...此外,第一个 Cleanup 以 Task id 1 作为参数调用(这是之前执行的任务,对吗?)并且此任务的状态为已取消(我从不在任何地方取消任务)。
有谁知道这里出了什么问题?

编辑:好的,根据 msdn,如果不满足继续的条件,则其任务将被取消。所以 ErrorHandler 被取消了,但是我怎样才能停止整个链(或通过清理和退出通知其他延续它已被取消)?

4

2 回答 2

0

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

正确设置延续链有时很棘手,但您可以使用组合函数(如Task.WhenAny.

如果您可以使用 async/await,则任务会大大简化。然后,您可以使用正常的控制流构造。您还可以使用迭代器模拟等待。

于 2013-08-03T21:41:41.327 回答
0

将 ErrorHandler -> Cleanup 延续设置为 OnlyOnRanToCompletion 或 NotOnCanceled 将起作用。另外,也许您可​​以使用异步简化一些事情。像这样的东西可以工作:

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

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

于 2013-08-05T09:35:21.897 回答