【问题标题】:Properly handling HttpClient exceptions within async / await在 async / await 中正确处理 HttpClient 异常
【发布时间】:2013-10-02 18:33:43
【问题描述】:

我希望有人能对我在使用 HttpClient 处理异步/等待异常时遇到的问题有所启发。我编写了一些代码来说明,它正在 Windows Phone 8 设备和模拟器上执行:

    private async void SearchButton_Click(object sender, EventArgs e)
    {
        try
        {
            HttpClient client = new HttpClient();
            System.Diagnostics.Debug.WriteLine("BEGIN FAULTY REQUEST:");
            string response = await client.GetStringAsync("http://www.ajshdgasjhdgajdhgasjhdgasjdhgasjdhgas.tk/");
            System.Diagnostics.Debug.WriteLine("SUCCESS:");
            System.Diagnostics.Debug.WriteLine(response);
        }
        catch (Exception exception)
        {
            System.Diagnostics.Debug.WriteLine("CAUGHT EXCEPTION:");
            System.Diagnostics.Debug.WriteLine(exception);
        }
    }

点击调用此函数的按钮,在调试器控制台中产生以下输出,最有趣的是粗体中的输出:

开始错误请求:

System.Windows.ni.dll 中出现“System.Net.WebException”类型的异常,并且在托管/本机边界之前未处理

System.Windows.ni.dll 中出现“System.Net.WebException”类型的异常,并且在托管/本机边界之前未处理

在 mscorlib.ni.dll 中发生了“System.Net.Http.HttpRequestException”类型的第一次机会异常

“System.Net.Http.HttpRequestException”类型的异常发生在 mscorlib.ni.dll 中,并且在托管/本机边界之前未处理

发现异常:

(在这里打印出 HttpRequestException)

当然,在这种情况下,我预计会出现错误,因为我调用的 URL 是无意义的。我在这里不明白的是,当输出同时报告异常已被捕获时,为什么调试器会报告未处理异常。此外,在打印输出时,应用程序的 UI 端的响应速度会大大降低,这表明可能有问题。

这不是在使用 async 和 await 时处理异常的方法吗?我很感激任何意见!谢谢。

【问题讨论】:

  • 就响应性而言,您不应在 UI 事件中运行长时间的进程。这些应该是快速且长时间运行的进程应该在另一个线程中完成。试试BackgroundWorkermsdn.microsoft.com/en-us/library/…

标签: c# .net asynchronous windows-phone-8 async-await


【解决方案1】:

由于您使用的是HttpClient,请尝试使用response.EnsureSuccessStatusCode();

现在HttpClient会在响应状态不是成功码时抛出异常。

try
{
    HttpResponseMessage response = await client.GetAsync("http://www.ajshdgasjhdgajdhgasjhdgasjdhgasjdhgas.tk/");
    response.EnsureSuccessStatusCode();    // Throw if not a success code.

    // ...
}
catch (HttpRequestException e)
{
    // Handle exception.
}

代码的原始来源:http://www.asp.net/web-api/overview/advanced/calling-a-web-api-from-a-net-client

【讨论】:

  • 如果你想让response成为HttpResponseMessage类型,你必须使用client.GetAsync而不是client.GetStringAsync。
  • 我一直在尝试将错误请求 (400) 作为异常捕获。就我而言,我的应用程序没有到达网络服务器的有效端点(可能是因为服务器没有更改它)。我一直在挠头半小时,谷歌搜索为什么这没有作为例外。你的回答真的很有帮助。这是处理这类事情的正确方法吗?将错误请求作为异常捕获?谢谢。
【解决方案2】:

调试器告诉你这个异常是第一次机会。当调试器附加到您的进程时,它会收到有关抛出的每个异常的通知,然后根据调试器的配置方式,它将决定如何处理它。您可以通过What is first chance exception?了解更多详情。

附带说明,仅捕获特定异常以便您了解预期的异常以及原因。

【讨论】:

  • 谢谢,我会读一读!我同意你的旁注,我的实际情况不同,我只是写这个来说明我的问题。
【解决方案3】:

这是调试器的工件。它确定一个异常是“未捕获的”,因为它还没有被捕获。在这种情况下,这是预期行为。

您正在正确处理异常。

【讨论】:

  • 我会说它被标记为“未捕获”,因为它不是被用户代码捕获的,而是被 TPL 捕获的。
  • 未处理异常。它是隐藏的(即使它被记录到 Debug.WriteLine 不会出现在发布模式中)。内置发布时,如果 http 调用失败,您将不知道原因(甚至失败)。
  • @Stuart:对于问题中贴出的代码,异常会被捕获。
猜你喜欢
  • 2021-04-10
  • 1970-01-01
  • 2020-05-15
  • 2018-04-13
  • 1970-01-01
  • 1970-01-01
  • 2017-01-31
  • 2017-04-12
相关资源
最近更新 更多