编辑: 这个问题看起来可能是同一个问题,但没有回复......
编辑:在测试用例5中,任务似乎陷入WaitingForActivation状态.
我在.NET 4.5中使用System.Net.Http.HttpClient遇到了一些奇怪的行为 - 其中"等待"调用(例如)的结果httpClient.GetAsync(...)将永远不会返回.
只有在使用新的async/await语言功能和Tasks API时才会出现这种情况 - 在仅使用continuation时,代码似乎始终有效.
下面是一些重现问题的代码 - 将其放入Visual Studio 11中新的"MVC 4 WebApi项目"中,以显示以下GET端点:
/api/test1
/api/test2
/api/test3
/api/test4
/api/test5 <--- never completes
/api/test6
Run Code Online (Sandbox Code Playgroud)
这里的每个端点都返回相同的数据(来自stackoverflow.com的响应头),除非/api/test5从未完成.
代码重现:
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
/// …Run Code Online (Sandbox Code Playgroud) 我目前正在实现一个System.Web.Http.IActionFilter调用内部服务来确定当前请求是否可以继续.我遇到的问题是返回一个Task<T1>基于a封装的逻辑Task<T2>.
一个例子可能有帮助.
内部服务API使用Tasks实现.使用.NET 4.5的异步/等待逻辑是微不足道的:
public async Task<HttpResponseMessage> ExecuteActionFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
{
UserAuthenticationResult authResult = await HitInternalServiceAsync();
if (!authResult.IsAuthenticated)
{
throw new HttpResponseException("User is not authenticated", HttpStatusCode.Unauthorized);
}
return await continuation();
}
Run Code Online (Sandbox Code Playgroud)
但是,使用.NET 4.0中的旧Task API会更加困难;
public Task<HttpResponseMessage> ExecuteActionFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
{
return HitInternalServiceAsync()
.ContinueWith(t1 => {
UserAuthenticationResult authResult = t1.Result;
if (!authResult.IsAuthenticated)
{
throw new HttpResponseException("User is not authenticated", HttpStatusCode.Unauthorized);
}
//Hack hack - this …Run Code Online (Sandbox Code Playgroud)