@H_404_1@我有一个任务< T:
Task<A> soMetask = ...
此任务可能导致成功,故障或取消.
当任务成功时,我想转换结果,如果不成功则保存结果.
当soMetask引发异常时,这似乎是非常困难的.
我试过的
Task<B> resultTask = StartMyTask().ContinueWith<B>( t => Foo(t.Result),TaskContinuationOptions.OnlyOnRanToCompletion);
如果某些任务发生故障,则会导致resultTask被取消.我想要它的错.
Task<B> resultTask = StartMyTask().ContinueWith<B>( t => Foo(t.Result));
这会导致Visual Studio调试器,因为.Result抛出异常.如果我按F5,resultTask如预期的错误,但它闻起来.
有没有办法让resultTask与soMetask的相同的结果,如果soMetask的错误?
本质上我要做的就是用任务来表达这样的东西:
int F() { throw new SomeException(); } string G(int x) { return x.ToString(); } try { string result = G(F()); } catch (SomeException e) { ... }
解决方法
任务延续是独立的.它们可以用于构建您想要的,但它们不是专门针对该场景设计的.
要问的第一个问题是:关系可以被视为父/子关系(例如,Foo将是StartMyTask的父级)?如果这是有道理的话,那么你可以利用从小孩到家长的状态.
如果将Foo视为“父”,并将StartMyTask视为“小孩”,则设计不成功,那么还有其他选项.连续性对于您需要的是一个低级别(记住,他们只是“在其他任务完成时运行此任务”).
听起来你可能会试图做一些更像“管道”的事情.目前,Rx更适合这种事情.
基于任务的管道并不在这里. ParallelExtensionsExtras library有一个基于任务的管道类,Async CTP有一个TPL数据流库,但目前这两者都不够开发. (例如,Pipeline坚持在独立的线程中运行管道的每个阶段,而Dataflow没有机制可以自动传播异常甚至完成).
所以,如果不能使用Rx,那么我将为任务编写自己的“PipelineTransform”扩展方法,并使用显式TCS来正确处理所有三个完成情况.