2013-03-08 22 views
1

我在調用HttpClient類和異步調用時遇到問題。我從page_load調用函數List()。從行HttpResponseMessage返回的響應response = await client.GetAsync(str);永遠不會回來完成它。asp.net中的HttpClient調用

我不明白我在做什麼錯誤。以下是我的代碼:

 protected void Page_Load(object sender, EventArgs e) 
     { 
      Task<string> s= List(product); 
     } 

     protected async Task<string> List(string ProductType) 
     { 
      string str = "http://xx.xx.com/wiki/api.php"; 


      using (HttpClient client = new HttpClient()) 
      { 
       client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes(String.Format("{0}:{1}", "username", "password")))); 
       HttpResponseMessage response = await client.GetAsync(str); 

       response.EnsureSuccessStatusCode(); 

       string content = await response.Content.ReadAsStringAsync(); 
      } 
      return content; 
     } 

它從不執行以下行。

response.EnsureSuccessStatusCode(); 
string content = await response.Content.ReadAsStringAsync(); 

請幫忙。提前致謝。

回答

1

你永遠不表明發生了什麼任務Page_Load,但鑑於你的症狀和事實Page_Loadasync,我打賭你調用ResultWait,而不是await荷蘭國際集團它。

當你這樣做,你cause a deadlock。鏈接到我的博客詳細解釋了這一點,但其要點是,await將捕獲和恢復當前的「上下文」。在ASP.NET中,這是一個請求上下文,並且請求上下文一次只允許執行一個線程。所以,如果你調用ResultWait(當你在請求上下文中),你將在請求上下文中阻塞一個線程,直到Task<string>完成。同時,當HttpClient得到它的迴應時,它會在await client.GetAsync(str)之後嘗試恢復。但是請求上下文一次只允許一個線程,並且該線程被阻塞,等待Task完成。由於List無法完成,因爲上下文很忙,所以會出現死鎖。

爲了防止死鎖,請按照這兩個best practices (from my recent MSDN article)

  1. 使用async一路。也就是說,使用await而不是ResultWait
  2. 使用ConfigureContext(false)在您的「庫」的代碼,即在每List應該await實際上是await ... .ConfigureAwait(false);
+0

感謝斯蒂芬對我的幫助。它有助於。 – Hiral 2013-03-13 15:24:41

相關問題