问题
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?
console code (this works):
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);
}
}
}
and this is frozen when it hits 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);
}
}
}
回答1:
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.
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
).
To fix this, use async
all the way:
private async void button1_Click(object sender, EventArgs e)
{
await RunAsync();
}
回答2:
You are waiting for the result of your async task. That blocks the UI thread until that task is completed.
Do not wait for completion in your button1_Click
event handler.
来源:https://stackoverflow.com/questions/24316790/http-client-frozes-in-windows-form-app