2013-03-08 19 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

相关问题