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

c# – 有一个简单的方法来返回一个异常的任务吗?

发布时间:2020-12-15 04:14:39 所属栏目:百科 来源:网络整理
导读:我的理解是返回Task.FromResult(foo)是一个简单的简写: var tcs = new TaskCompletionSourceTFoo();tcs.SetResult(foo);return tcs.Task; 是否有一些等效的任务返回异常状态? var tcs = new TaskCompletionSourceTFoo();tcs.SetException(new NotSupported
我的理解是返回Task.FromResult(foo)是一个简单的简写:
var tcs = new TaskCompletionSource<TFoo>();
tcs.SetResult(foo);
return tcs.Task;

是否有一些等效的任务返回异常状态?

var tcs = new TaskCompletionSource<TFoo>();
tcs.SetException(new NotSupportedException()); // or whatever is appropriate
return tcs.Task;

我看不到任何类似Task.FromException的东西.或者更恰当的是抛出异常而不返回任务?

解决方法

My understanding is that return Task.FromResult(foo) is a simple
shorthand for… [TaskCompletionSource.SetResult].

实际上,Task.FromResult不使用TaskCompletionSource,所以its implementation比这简单得多.

Is there some equivalent for a task that returns an exception state?

我估计TaskCompletionSource将是最好的选择.你也可以这样做:

static Task FromExAsync(Exception ex) 
{
    var task = new Task(() => { throw ex; });
    task.RunSynchronously();
    return task;
}

异常将不会在返回的任务之外传播,直到通过等待任务或task.Wait()观察到,这应该是一个期望的行为.

请注意,如果传递给FromExAsync的异常是一个活动异常(即已经被抛出并被其他地方捕获),那么像这样重新抛出它将会使当前的堆栈跟踪和Watson存储在异常存储信息中的信息丢失.有两种处理方式:

>使用AggregateException包装异常.这将使原始异常可用作AggregateException.InnerException:

static Task FromExAsync(Exception ex) 
{
    var task = new Task(() => { throw new AggregateException(ex); });
    task.RunSynchronously();
    return task;
}

>使用ExceptionDispatchInfo.Capture来处理活动异常的状态:

static Task FromExAsync(Exception ex) 
{
    var ei = System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(ex);
    var task = new Task(() => { ei.Throw(); });
    task.RunSynchronously();
    return task;
}

最后,也许最简单但最糟糕的选择(由于overhead of the state machine和编译器警告)是从异步方法抛出的:

static async Task FromExAsync(Exception ex)
{
    throw ex;
}

(编辑:李大同)

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

    推荐文章
      热点阅读