C# 任务连续性奇怪的行为
我构建了一个带有条件延续的小任务链,但是我遇到了一些奇怪的行为。 我的链条看起来像这样:C# 任务连续性奇怪的行为,c#,task-parallel-library,C#,Task Parallel Library,我构建了一个带有条件延续的小任务链,但是我遇到了一些奇怪的行为。 我的链条看起来像这样: LoadSettings (OnlyOnFaulted)-> ErrorHandler (none)-> Cleanup (none)-> Exit | (OnlyOnRanToCompletion) CheckForUpdates (OnlyOnFaulted)-> ErrorHandler (none)-> Cleanup (none)-> Exit |
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->CheckForUpdate->…)。但是我得到了这种行为:
加载设置->检查更新->清理->退出->清理->。。。 此外,第一次清理将以任务id 1作为参数调用(这是之前执行的任务,对吗?),并且此任务的状态为“已取消”(并且我从不在任何地方取消任务)。
有人知道这里出了什么问题吗
编辑:根据msdn,如果不满足继续的条件,则其任务将被取消。因此,ErrorHandler被取消,但我如何停止整个链(或通过cleanup和exit通知其他continuations它已被取消)?使用
任务。当任何时,您都可以创建一个在成功处理程序或错误处理程序完成时运行的任务。退出该任务后,您将继续执行清理
有时,正确设置延续链是很困难的,但您可以使用组合函数(如Task.wheny
)构建相当复杂的流图
如果可以使用async/wait,那么任务将简化很多。然后可以使用普通控制流构造。您还可以使用迭代器模拟wait。设置ErrorHandler->Cleanup continuation,因为只有OnArntoCompletion或NotIncanceled可以工作。另外,也许您可以使用async简化一些事情。类似这样的方法可能会奏效:
try {
var settings = await LoadSettings();
var updatesNeeded = await CheckForUpdates(settings);
await Update(updatesNeeded);
} catch (Exception e) {
ErrorHandler(e);
} finally {
Cleanup();
}
请注意,这里的错误处理和清理是同步的,因为您不能在catch/finally块中等待。您可以通过只将异常存储在一个变量中来解决这个问题,稍后检查该变量是否为null并将其传递给异步错误处理程序