繁体   English   中英

如何从任务中抛出/捕获内部异常?

[英]How to throw/catch the inner exception from a task?

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

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
}

现在我正在实现一个DelegatingHandler并覆盖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之前,一切都按预期工作。 异常冒泡到调用者,但是,异常是AggregrateException

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

当在任务中引发异常时,然后使用Result属性,您将得到AggregateException ,其中真正的异常在此AggregateException object 的InnerException属性中(您的异常由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;

AggregrateException是许多异常的合并,因为async方法可以在其执行时抛出许多异常 .net 使用此 class 来返回所有异常。

要访问内部异常,它有一个名为InnerExceptions的属性,它是一个包含所有抛出异常的只读集合。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM