Изменить:Этот вопрос выглядит так, как будто это та же проблема, но нет ответов...
Изменить: В тестовом примере 5 задача зависла в состоянии WaitingForActivation
.
Я столкнулся со странным поведением при использовании System.Net.Http.HttpClient в .NET 4.5, где «ожидание» результата вызова (например) httpClient.GetAsync(...)
никогда не вернется.
Это происходит только при определенных обстоятельствах при использовании новых функций языка async/await и Tasks API — кажется, что код всегда работает при использовании только продолжений.
Вот некоторый код, который воспроизводит проблему — поместите его в новый «проект MVC 4 WebApi» в Visual Studio 11, чтобы предоставить следующие конечные точки GET:
/api/test1
/api/test2
/api/test3
/api/test4
/api/test5 <--- never completes
/api/test6
Каждая из конечных точек здесь возвращает одни и те же данные (заголовки ответов из stackoverflow.com), за исключением /api/test5
, который никогда не завершается.
Код для воспроизведения:
public class BaseApiController : ApiController
{
///
/// Retrieves data using continuations
///
protected Task Continuations_GetSomeDataAsync()
{
var httpClient = new HttpClient();
var t = httpClient.GetAsync("http://stackoverflow.com", HttpCompletionOption.ResponseHeadersRead);
return t.ContinueWith(t1 => t1.Result.Content.Headers.ToString());
}
///
/// Retrieves data using async/await
///
protected async Task 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
{
///
/// Handles task using Async/Await
///
public async Task Get()
{
var data = await Continuations_GetSomeDataAsync();
return data;
}
}
public class Test2Controller : BaseApiController
{
///
/// Handles task by blocking the thread until the task completes
///
public string Get()
{
var task = Continuations_GetSomeDataAsync();
var data = task.GetAwaiter().GetResult();
return data;
}
}
public class Test3Controller : BaseApiController
{
///
/// Passes the task back to the controller host
///
public Task Get()
{
return Continuations_GetSomeDataAsync();
}
}
public class Test4Controller : BaseApiController
{
///
/// Handles task using Async/Await
///
public async Task Get()
{
var data = await AsyncAwait_GetSomeDataAsync();
return data;
}
}
public class Test5Controller : BaseApiController
{
///
/// Handles task by blocking the thread until the task completes
///
public string Get()
{
var task = AsyncAwait_GetSomeDataAsync();
var data = task.GetAwaiter().GetResult();
return data;
}
}
public class Test6Controller : BaseApiController
{
///
/// Passes the task back to the controller host
///
public Task Get()
{
return AsyncAwait_GetSomeDataAsync();
}
}