加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 在ContinueWith中重新发现之前的异常

发布时间:2020-12-15 17:42:17 所属栏目:百科 来源:网络整理
导读:介绍 在我的代码困惑了一段时间后,我发现异常并不一定通过ContinueWith传播: int zeroOrOne = 1;Task.Factory.StartNew(() = 3 / zeroOrOne) .ContinueWith(t = t.Result * 2) .ContinueWith(t = Console.WriteLine(t.Result)) .ContinueWith(_ = SetBusy(f
介绍

在我的代码困惑了一段时间后,我发现异常并不一定通过ContinueWith传播:

int zeroOrOne = 1;
Task.Factory.StartNew(() => 3 / zeroOrOne)
    .ContinueWith(t => t.Result * 2)
    .ContinueWith(t => Console.WriteLine(t.Result))
    .ContinueWith(_ => SetBusy(false))
    .LogExceptions();

在这个例子中,SetBusy行’重置’异常链,所以除了零异常不会被看到,随后在我的脸上吹起了“一个任务的异常没有被观察到…”

所以…我写了一个自己的一些扩展方法(吨不同的重载,但基本上都这样做):

public static Task ContinueWithEx(this Task task,Action<Task> continuation)
{
     return task.ContinueWIth(t =>
     {
         if(t.IsFaulted) throw t.Exception;
         continuation(t);
     });
}

多搜索一下,我发现了this博客文章,他在那里提出了一个类似的解决方案,但是使用了一个TaskCompletionSource(其中释义)如下所示:

public static Task ContinueWithEx(this Task task,Action<Task> continuation)
{
     var tcs = new TaskCompletionSource<object>();
     return task.ContinueWith(t =>
     {
         if(t.IsFaulted) tcs.TrySetException(t.Exception);
         continuation(t);
         tcs.TrySetResult(default(object));
     });
     return tcs.Task;
}

这两个版本是否严格等同?或者在t.Exception和tcs.TrySetException(t.Exception)之间有微妙的区别?

另外,事实上,整个互联网上显然只有一个人是这样做的,这表明我错过了这样做的惯用方式?

解决方法

两者之间的区别是微妙的.在第一个示例中,您将抛出该任务返回的异常.这将触发正常的异常在CLR中抛出和捕获,ContinueWith将捕获并包装它并将其传递给链中的下一个任务.

在第二个你调用TrySetException,它仍将包装异常并将其传递给链中的下一个任务,但不会触发任何try / catch逻辑.

一个ContinueWithEx之后的最终结果是AggregateException(AggregateException(DivideByZeroException))).我唯一的区别是,内部的AggregateException在第一个例子中设置了一个堆栈跟踪(因为它被抛出),而在第二个例子中没有堆栈跟踪.

也不可能比另一个快得多,但我个人更喜欢第二个来避免不必要的投掷.

我做了这样的事情,继续返回结果.我调用它选择,处理前一个任务被取消的情况,提供重载来修改异常,而不是或除了结果,并使用ExecuteSynchronously选项.当继续本身返回一个Task时,我调用Then而不是基于this article的代码

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读