2014-06-19 131 views
0

我跟随this example,它在一个控制台应用程序,但后来我尝试了一个Windows窗体应用程序,它在结果是await client.GetAsync("api/branches/1035") 它是如何不同?http客户端冻结在Windows窗体应用

控制台代码(这个工程):

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); 
      } 

     } 
    } 
+0

为什么你的button1_Click仍在试图写入控制台?它不再是一个控制台应用程序。 –

+0

@KenWhite是我的坏,忘了那条线,我试图从我的api得到一些“分支”,然后客户端应该返回他喜欢的那些 –

回答

5

你正在看到一个死锁,我explain fully on my blog。实质上,await将捕获“上下文”并使用它来恢复方法。在控制台应用中,这个“上下文”是线程池上下文,但在UI应用中,这个“上下文”是UI线程上下文。

进一步调用堆栈,你打电话Wait,它阻止该线程,直到任务完成。在控制台应用程序中,async方法在线程池线程上恢复;但在UI应用程序中,async方法无法在UI线程上恢复(因为UI线程在调用Wait时被阻止)。

为了解决这个问题,使用async一路:

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

真的很好,谢谢 –

2

您正在等待你的异步任务的结果。这阻止了UI线程,直到该任务完成。

不要等到您的button1_Click事件处理程序完成。

+0

所以我应该在哪里? –

+0

下载完成后你想做什么? –

+0

我的应用程序将读取分支的列表,然后客户将选择一些分支,我应该在哪里放置? –