2016-03-16 5 views
1

Приложения должны получать httpresponsemessage от LoginUser(), но она становится не отвечает.GetAsync: не возвращает HttpResponseMessage

private void button1_Click(object sender, EventArgs e) 
    { 
     if (LoginUser(tUser.Text, Password.Text).Result.IsSuccessStatusCode) 
     { 
      Notifier.Notify("Successfully logged in.. Please wait!"); 

     } 
     else 
     { 
      Notifier.Notify("Please check your Credential.."); 
     }    
    } 

public async Task<HttpResponseMessage> LoginUser(string userid, string password) 
    { 
     string URI = "http://api.danubeco.com/api/userapps/authenticate"; 

     using (var client = new HttpClient()) 
     { 
      client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("c291cmF2OmtheWFs"); 

      using (var response = await client.GetAsync(String.Format("{0}/{1}/{2}", URI, userid, password))) 
      { 
       return response; 
      } 
     } 
    } 

Пожалуйста, помогите!

+1

Удалить все асинхронный материал и убедитесь, что он работает. –

+0

Пожалуйста, взгляните на это http://www.dotnetperls.com/httpclient –

+1

Это приложение для пользовательского интерфейса? Если это так, вы вызываете тупик в 'LoginUser (...) .Result.IsSuccessStatusCode'. Подробнее здесь - http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html –

ответ

6

Вы блокируете поток пользовательского интерфейса и вызывают блокировку. From Stephen Cleary's blog (Просто замените GetJsonAsync с вашим методом LoginUser и GetStringAsync с client.GetAsync):

Так это то, что происходит, начиная с метода верхнего уровня (Button1_Click для UI/MyController.Get для ASP.NET):

  1. Метод верхнего уровня вызывает GetJsonAsync (в контексте UI/ASP.NET).

  2. GetJsonAsync запускает запрос REST, вызывая HttpClient.GetStringAsync (все еще в контексте).

  3. GetStringAsync возвращает незавершенную задачу, указывая, что запрос REST не завершен.

  4. GetJsonAsync ожидает задачу, возвращенную GetStringAsync. Контекст захвачен и будет использоваться для продолжения использования метода GetJsonAsync . GetJsonAsync возвращает незавершенную задачу , указывающую, что метод GetJsonAsync не завершен.

  5. Метод верхнего уровня синхронно блокирует задачу, возвращенную GetJsonAsync. Это блокирует контекстный поток.

  6. ... В конце концов, запрос REST будет завершен. Это завершает задачу, которая была возвращена GetStringAsync.

  7. Продолжение для GetJsonAsync теперь готово к запуску и ожидает, что контекст будет доступен, чтобы он мог выполняться в контексте.

  8. Тупик. Метод верхнего уровня блокирует поток контекста, ожидая завершения GetJsonAsync, и GetJsonAsync ждет контекста, который будет бесплатным, чтобы он мог завершить.

И простые доступные решения (в том числе из блога):

  1. В вашей «библиотеки» асинхронными методами, используйте ConfigureAwait (ложь), где это возможно.
  2. Не блокируйте задачи; используйте async полностью вниз.

2-е решения предполагает, что вы меняете button1_Click в:

private async void button1_Click(object sender, EventArgs e) 
{ 
    if ((await LoginUser(tUser.Text, Password.Text)).IsSuccessStatusCode) 
    { 
     Notifier.Notify("Successfully logged in.. Please wait!"); 

    } 
    else 
    { 
     Notifier.Notify("Please check your Credential.."); 
    }    
}