bto*_*rdz 0 c# httpclient async-await asp.net-web-api
我正在关注这个例子,它可以在一个控制台应用程序中运行,但后来我在一个Windows窗体应用程序中尝试了它并且它会在命中行时await client.GetAsync("api/branches/1035")
如何不同?
控制台代码(这是有效的):
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
当它击中时它会被冻结 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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
你看到了我在博客上完全解释的僵局.本质上,一个await将捕获"上下文"并使用它来恢复该async方法.在Console应用程序中,此"上下文"是线程池上下文,但在UI应用程序中,此"上下文"是UI线程上下文.
进一步调用堆栈,你正在调用Wait,它阻塞该线程直到任务完成.在Console应用程序中,该async方法在线程池线程上恢复; 但是在UI应用程序中,该async方法无法在UI线程上恢复(因为UI线程在调用中被阻止Wait).
要解决此问题,请一直使用async:
private async void button1_Click(object sender, EventArgs e)
{
await RunAsync();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2338 次 |
| 最近记录: |