【问题标题】:Can't catch Exception thrown from Task无法捕获任务抛出的异常
【发布时间】:2014-10-07 19:01:10
【问题描述】:

我一直在为这个问题摸不着头脑。我不知道这个异常是在哪里引发的。我到底应该在哪里捕捉到这个异常?这是System.Net.WebException。我想我只是没有得到任务和异步/等待。我知道我正在创建其他线程,这很好,但是我在哪里处理异常?

The remote server returned an error: (403) Forbidden.

代码如下:

public async void sendRequest(string database, string table, string where, bool isPost, int deviceType)
{
    string urlQuery = Constants.URL_QUERY + database + "/" + table + "?" + where;

    Debug.WriteLine("URL Query: " + urlQuery);

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(urlQuery);
    request.Method = isPost ? "POST" : "GET";
    request.ContentType = "application/json";

    try
    {
        Debug.WriteLine("getting response");
        WebResponse response = await makeAsyncRequest(request);
        Debug.WriteLine("response obtained");
        finishRequest(response);
    }
    catch (WebException e)
    {
        Debug.WriteLine("WebException caught");
    }
}

private async static Task<WebResponse> makeAsyncRequest(HttpWebRequest req)
{
    Task<WebResponse> task = Task.Factory.FromAsync<WebResponse>(req.BeginGetResponse, req.EndGetResponse, null);

    await task.ContinueWith(t =>
    {
        if (t.IsFaulted)
        {
            Debug.WriteLine("It's faulted.");
            t.Exception.Handle((x) =>
            {
                if (x is WebException)
                {
                    Debug.WriteLine("It's a web exception");
                    return true;
                }
                Debug.WriteLine("Exception?: " + x);
                return false;
            });
        }
    });
    Debug.WriteLine("returning task");
    return task.Result;
}

private static void finishRequest(WebResponse response)
{
    Debug.WriteLine("finishRequest called");
}

这是我在“输出”窗口中看到的内容:

2014-10-07 14:05:05.104 FormsTemplateiOS[1568:53280] getting response
[0:] getting response
Thread started:  #3
Thread started: <Thread Pool> #4
Thread started: <Thread Pool> #5
Thread started: <Thread Pool> #6
Thread started: <Thread Pool> #7
Thread started:  #8
[0:] 
2014-10-07 14:05:05.681 FormsTemplateiOS[1568:53326] It's faulted.
[0:] It's faulted.
[0:] 
2014-10-07 14:05:05.804 FormsTemplateiOS[1568:53326] It's a web exception
[0:] It's a web exception
Unhandled Exception:

System.Net.WebException: The remote server returned an error: (403) Forbidden.

Unhandled Exception:
System.Net.WebException: The remote server returned an error: (403) Forbidden.
  at System.Net.HttpWebRequest.CheckFinalStatus (System.Net.WebAsyncResult result) [0x0033b] in ///Library/Frameworks/Xamarin.iOS.framework/Versions/8.0.0.63/src/mono/mcs/class/System/System.Net/HttpWebRequest.cs:1718 
  at System.Net.HttpWebRequest.SetResponseData (System.Net.WebConnectionData data) [0x00165] in ///Library/Frameworks/Xamarin.iOS.framework/Versions/8.0.0.63/src/mono/mcs/class/System/System.Net/HttpWebRequest.cs:1485 
The program 'Mono' has exited with code 0 (0x0).
Debugging session ended.

编辑:

我根据 Stephen Cleary 的建议更新了 makeAsyncRequest(HttpWebRequest)。我仍然遇到同样的问题。

private async static Task<WebResponse> makeAsyncRequest(HttpWebRequest req)
{
    Task<WebResponse> task = Task.Factory.FromAsync<WebResponse>(req.BeginGetResponse, req.EndGetResponse, null);
    try
    {
        return await task;
    }
    catch (WebException e)
    {
        Debug.WriteLine("It's a WebException");
    }
    catch (Exception e)
    {
        Debug.WriteLine("Other Exception");
    }
    return null;
}

输出窗口:

2014-10-07 14:32:08.385 FormsTemplateiOS[1588:57008] getting response
[0:] getting response
Thread started:  #3
Thread started: <Thread Pool> #4
Thread started: <Thread Pool> #5
Thread started: <Thread Pool> #6
Thread started: <Thread Pool> #7
Thread started:  #8
Unhandled Exception:

System.Net.WebException: The remote server returned an error: (403) Forbidden.

Unhandled Exception:
System.Net.WebException: The remote server returned an error: (403) Forbidden.
  at System.Net.HttpWebRequest.CheckFinalStatus (System.Net.WebAsyncResult result) [0x0033b] in ///Library/Frameworks/Xamarin.iOS.framework/Versions/8.0.0.63/src/mono/mcs/class/System/System.Net/HttpWebRequest.cs:1718 
  at System.Net.HttpWebRequest.SetResponseData (System.Net.WebConnectionData data) [0x00165] in ///Library/Frameworks/Xamarin.iOS.framework/Versions/8.0.0.63/src/mono/mcs/class/System/System.Net/HttpWebRequest.cs:1485 
The program 'Mono' has exited with code 0 (0x0).
Debugging session ended.

【问题讨论】:

标签: c# async-await task webexception


【解决方案1】:

我知道我正在创建其他线程,这很棒

不,实际上。您可能想阅读我的async intro

还有:

  • 避免async void
  • 使用await 而不是ContinueWith

您可能还会发现我的 async best practices 文章很有帮助。

private async static Task<WebResponse> MakeRequestAsync(HttpWebRequest req)
{
  Task<WebResponse> task = Task.Factory.FromAsync<WebResponse>(req.BeginGetResponse, req.EndGetResponse, null);
  try
  {
    return await task;
  }
  catch (WebException ex)
  {
    Debug.WriteLine("It's a web exception");
  }
  catch (Exception ex)
  {
    Debug.WriteLine("It's not a web exception.");
  }
}

最后一点,请考虑使用HttpClient 而不是HttpWebRequestHttpClient 专为 async 使用而设计。

【讨论】:

  • 如果任务不在单独的线程上,那为什么它是 System.Threading 的一部分?
  • 这是出于历史原因。 Task 最初是作为任务并行库的一部分引入的,主要用于表示要在线程上执行的工作。它已被重新用作任意“异步操作”。
  • 我需要能够将请求标头和方法设置为 POST 或 GET。这可以用 HttpClient 完成吗?滚动浏览属性和方法,我看不到任何允许这样做的东西。
  • 我试过这段代码。同样的异常仍未被捕获。我会将更新后的代码添加到我的问题中。
  • @JaredPrice:“未捕获”是指它只是在调试器中被捕获吗?因为它会在运行时被catch 捕获。
猜你喜欢
  • 2021-09-02
  • 2011-04-05
  • 2015-09-23
  • 2013-08-02
  • 2018-05-30
  • 1970-01-01
  • 1970-01-01
  • 2019-01-14
  • 2012-12-02
相关资源
最近更新 更多