2014-06-19 86 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

我的應用程序將讀取分支的列表,然後客戶將選擇一些分支,我應該在哪裏放置? –