Windows窗体应用程序中的HTTP客户端错误 [英] http client frozes in windows form app

查看:95
本文介绍了Windows窗体应用程序中的HTTP客户端错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在关注此示例,它可以在控制台应用程序中使用,但是随后我在Windows窗体应用程序中尝试了该应用程序,当它击中await client.GetAsync("api/branches/1035")行时,它就会崩溃 有什么不同吗?

I am following this example, and it works in a console application, but then I tried in a windows form app and it forzes, when in hits the line await client.GetAsync("api/branches/1035") how is it diferent?

控制台代码(可行):

static void Main()
    {
        RunAsync().Wait();
    }

    static async Task RunAsync()
    {
        using (var client = new HttpClient())
        {
            client.BaseAddress = new Uri("http://localhost:49358/");

           client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            HttpResponseMessage response = await client.GetAsync("api/branches/1035");

            if (response.IsSuccessStatusCode)
            {
                branch branch = await response.Content.ReadAsAsync<branch>();
                Console.WriteLine("{0}\t${1}", branch.Id, branch.Color);
            }
        }
    }

,当它命中await client.GetAsync("api/branches/1035")

private void button1_Click(object sender, EventArgs e)
    {
        RunAsync().Wait();
    }

    static async Task RunAsync()
    {
        using (var client = new HttpClient())
        {
            client.BaseAddress = new Uri("http://localhost:49358/");
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            HttpResponseMessage response = await client.GetAsync("api/branches/1035");

            if (response.IsSuccessStatusCode)
            {
                Branch branch = await response.Content.ReadAsAsync<Branch>();
                Console.WriteLine("{0}\t${1}", branch.Id, branch.Color);
            }

        }
    }

推荐答案

您看到的是我async方法.在控制台应用程序中,此上下文"是线程池上下文,但是在UI应用程序中,此上下文"是UI线程上下文.

You're seeing a deadlock that I explain fully on my blog. Essentially, an await will capture a "context" and use that to resume the async method. In the Console app, this "context" is the thread pool context, but in the UI app, this "context" is the UI thread context.

在调用堆栈的上方,您正在调用Wait,它将阻塞该线程,直到任务完成.在控制台应用程序中,async方法在线程池线程上恢复;但是在UI应用程序中,async方法无法在UI线程上恢复(因为UI线程在对Wait的调用中被阻止).

Further up the call stack, you're calling Wait, which blocks that thread until the task completes. In the Console app, the async method resumes on a thread pool thread; but in the UI app, the async method cannot resume on the UI thread (because the UI thread is blocked in the call to Wait).

要解决此问题,请完全使用async:

To fix this, use async all the way:

private async void button1_Click(object sender, EventArgs e)
{
  await RunAsync();
}

这篇关于Windows窗体应用程序中的HTTP客户端错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆