首页 > 解决方案 > 如何从任务中抛出/捕获内部异常?

问题描述

假设我有一个简单的方法:

private void MyMethod()
{
    try {
        myService.Do();
    } catch (MyException ex) {}
}

我有一个使用 的服务,HttpClient我这样做:

public void Do()
{
   var response = client.GetAsync(url).Result; //Alas it's not async till now
}

现在我正在实施 aDelegatingHandler并覆盖SendAsync

protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
    return await base.SendAsync(request, cancellationToken)
        .ContinueWith<HttpResponseMessage>(task =>
        {
            HttpResponseMessage response = task.Result;

            if (response.StatusCode == HttpStatusCode.NotFound)
            {
                throw new MyException();
            }

            return response;
        }).ConfigureAwait(false);
}

一切都按预期工作,直到在MyException这里抛出 a 。异常冒泡到调用者,但是,异常是AggregrateException.

有没有办法抛出实际的异常本身,这样就不需要对应用程序范围内的代码进行重大更改?

标签: c#winforms

解决方案


当在任务中引发异常时,使用Result属性您将获得AggregateException真正的异常在InnerExceptionAggregateException对象的属性中的位置(您的异常由 包裹AggregateException)。

要获得真正的异常(未包装的异常),您可以使用GetAwaiter().GetResult()

var result = taskThatThrowsException.GetAwaiter().GetResult();

您也可以使用Result属性,但是您应该为异常处理指定一些条件;

try
{
    var result = taskThatThrowsException.Result;
}
catch (AggregateException ex) when (ex.InnerException is MyException myException)
{
    // use myException - it is your true unwrapped exception
}

但是你不应该阻塞异步代码- 你应该异步等待 - 使用await你也会得到你真正的解包异常:

var result = await taskThatThrowsException;

推荐阅读