当前位置: 首页 > 编程语言 > C#

在ContinueWith中重新抛出之前的异常分享

时间:2023-04-11 01:53:18 C#

Rethrow在ContinueWith中的之前的异常介绍把我的代码搞糊涂了一段时间,发现异常不一定通过ContinueWith传播:intzeroOrOne=1;Task.Factory.StartNew(()=>3/zeroOrOne).ContinueWith(t=>t.Result*2).ContinueWith(t=>Console.WriteLine(t.Result)).ContinueWith(_=>SetBusy(false))).LogExceptions();在此示例中,SetBusy行“重置”异常链,因此看不到被零除的异常,随后以“我没有观察到任务异常...”展开。所以...我自己写了一个小扩展方法(有很多不同的重载,但它基本上是这样做的):publicstaticTaskContinueWithEx(thisTasktask,Actioncontinuation){returntask.ContinueWIth(t=>{(t.IsFaulted)throwt.Exception;continuation(t);});搜索了一下,我发现这篇博文他提出了一个类似的解决方案,但是使用TaskCompletionSource,(释义)看起来像这样:publicstaticTaskContinueWithEx(thisTasktask,Actioncontinuation){returntask.ContinueWith(t=>{if(t.IsFaulted)tcs.TrySetException(t.Exception);continuation(t);tcs.TrySetResult(default(object));});返回tcs.Task;问题这两个版本是否相同?还是throwt.Exception和tcs.TrySetException(t.Exception)之间存在细微差别?此外,在整个互联网上显然只有一个人这样做这一事实是否表明我缺少一种惯用的方式来做到这一点?两者之间的区别是微妙的。在第一个示例中,您将抛出从任务返回的异常。这将触发CLR抛出并捕获的正常异常,ContinueWith将捕获并包装它并将其传递给链中的下一个任务。在第二个中,您调用TrySetException,它仍然会包装异常并将其传递给链中的下一个任务,但不会触发任何try/catch逻辑。ContinueWithEx之后的最终结果是AggregateException(AggregateException(DivideByZeroException))。我看到的唯一区别是内部AggregateException在第一个示例中设置了堆栈跟踪(因为它被抛出),而在第二个示例中没有堆栈跟踪。两者都不太可能比另一个快得多,但我个人更喜欢后者以避免不必要的抛出。我在延续返回结果的地方做了类似的事情。我称之为Select,处理上一个任务被取消的情况,提供重载来修改异常而不是结果,或者使用ExecuteSynchronously选项。当延续本身返回一个任务时,我调用了Then。根据本文代码,以上就是C#学习教程:在ContinueWith中重新抛出之前的异常。如果对大家有用,需要进一步了解C#学习教程,希望大家多多关注—本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: