簡體   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