2013-03-08 3 views
1

У меня возникла проблема при вызове класса HttpClient и асинхронного вызова. Я вызываю функцию List() из page_load. Вызовы возвращаются из строки HttpResponseMessage response = ожидают client.GetAsync (str); и никогда не возвращается, чтобы закончить его.HttpClient call in asp.net

Я не понимаю, какую ошибку я делаю. Ниже приведен мой код:

 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_Load не является async, я держу пари, что вы звоните Result или Wait вместо await ИНГ его.

Когда вы это сделаете, вы cause a deadlock. Ссылка на мой блог объясняет это подробно, но суть в том, что await будет захватывать и восстанавливать текущий «контекст». В ASP.NET это контекст запроса, и контекст запроса разрешает только один поток, выполняемый в нем за раз. Итак, если вы вызываете Result или Wait (пока вы находитесь в контексте запроса), вы блокируете поток в этом контексте запроса до завершения Task<string>. Между тем, когда HttpClient получает ответ, он пытается возобновить работу после await client.GetAsync(str). Но контекст запроса будет разрешать только один поток за раз, и этот поток блокируется, ожидая завершения Task. Поскольку List не может завершить, потому что контекст занят, у вас есть тупик.

Для предотвращения тупиков, выполните эти два best practices (from my recent MSDN article):

  1. Используйте async весь путь. То есть, используйте await вместо Result или Wait.
  2. Использование ConfigureContext(false) в вашей «библиотеки» кода, то есть, каждый await в List должно быть на самом деле await ... .ConfigureAwait(false);
+0

Спасибо Стивену за помощь мне. Помогает. – Hiral