HttpClient.GetAsync (…) nigdy nie powraca podczas używania await / async
Edytować: To pytanie wygląda na to, że może być ten sam problem, ale nie ma odpowiedzi ...
Edytować: W przypadku testowym 5 zadanie wydaje się być zablokowaneWaitingForActivation
stan.
Spotkałem się z pewnym dziwnym zachowaniem przy użyciu System.Net.Http.HttpClient w .NET 4.5 - gdzie „oczekiwanie” na wynik wywołania (np.)httpClient.GetAsync(...)
nigdy nie wróci.
Dzieje się tak tylko w pewnych okolicznościach, gdy używana jest nowa funkcjonalność async / await language i Tasks API - kod zawsze wydaje się działać przy użyciu tylko kontynuacji.
Oto kod, który odtwarza problem - upuść go w nowym projekcie „MVC 4 WebApi” w Visual Studio 11, aby pokazać następujące punkty końcowe GET:
<code>/api/test1 /api/test2 /api/test3 /api/test4 /api/test5 <--- never completes /api/test6 </code>
Każdy z punktów końcowych zwraca tutaj te same dane (nagłówki odpowiedzi ze stackoverflow.com), z wyjątkiem/api/test5
który nigdy się nie kończy.
Kod do odtworzenia:
<code>public class BaseApiController : ApiController { /// <summary> /// Retrieves data using continuations /// </summary> protected Task<string> Continuations_GetSomeDataAsync() { var httpClient = new HttpClient(); var t = httpClient.GetAsync("http://stackoverflow.com", HttpCompletionOption.ResponseHeadersRead); return t.ContinueWith(t1 => t1.Result.Content.Headers.ToString()); } /// <summary> /// Retrieves data using async/await /// </summary> protected async Task<string> AsyncAwait_GetSomeDataAsync() { var httpClient = new HttpClient(); var result = await httpClient.GetAsync("http://stackoverflow.com", HttpCompletionOption.ResponseHeadersRead); return result.Content.Headers.ToString(); } } public class Test1Controller : BaseApiController { /// <summary> /// Handles task using Async/Await /// </summary> public async Task<string> Get() { var data = await Continuations_GetSomeDataAsync(); return data; } } public class Test2Controller : BaseApiController { /// <summary> /// Handles task by blocking the thread until the task completes /// </summary> public string Get() { var task = Continuations_GetSomeDataAsync(); var data = task.GetAwaiter().GetResult(); return data; } } public class Test3Controller : BaseApiController { /// <summary> /// Passes the task back to the controller host /// </summary> public Task<string> Get() { return Continuations_GetSomeDataAsync(); } } public class Test4Controller : BaseApiController { /// <summary> /// Handles task using Async/Await /// </summary> public async Task<string> Get() { var data = await AsyncAwait_GetSomeDataAsync(); return data; } } public class Test5Controller : BaseApiController { /// <summary> /// Handles task by blocking the thread until the task completes /// </summary> public string Get() { var task = AsyncAwait_GetSomeDataAsync(); var data = task.GetAwaiter().GetResult(); return data; } } public class Test6Controller : BaseApiController { /// <summary> /// Passes the task back to the controller host /// </summary> public Task<string> Get() { return AsyncAwait_GetSomeDataAsync(); } } </code>