【发布时间】:2012-05-03 02:40:05
【问题描述】:
我目前正在实现一个System.Web.Http.IActionFilter,它调用一个内部服务来确定当前请求是否可以继续。我遇到的问题是根据Task<T2> 封装的一段逻辑返回Task<T1>。
一个例子可能会有所帮助。
内部服务 API 是使用 Tasks 实现的。使用 .NET 4.5 的 async/await 的逻辑很简单:
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();
}
但是在 .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 blocks the thread until the task retuned by continuation() completes
return continuation().Result;
});
}
当身份验证检查成功时,困难的部分就来了——然后我想等待延续函数返回的任务。
使用 .NET 4.0 时,我似乎在等待 continuation() 任务完成时明确阻止,而不是在 我的任务时指示 Tasks API 自动继续 continuation() 任务完成了。
问题:这是在 .NET 4.0 中实现此行为的唯一方法吗?
给定一个足够复杂的内部服务 API,我可以很容易地看到等待其他任务的任务数量迅速增加。
编辑: 看起来上面的 4.0 代码也不可行 - 因为延续 lambda 不会在 HttpContext.Current 等 ASP.NET 线程上下文服务中执行不可用。更好的实现是......
public Task<HttpResponseMessage> ExecuteActionFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
{
Task<UserAuthenticationResult> authResultTask = HitInternalServiceAsync();
var authResult = authResultTask.Result;
if (!authResult.IsAuthenticated)
{
throw new HttpResponseException("User is not authenticated", HttpStatusCode.Unauthorized);
}
return continuation();
}
【问题讨论】:
标签: .net c#-4.0 asynchronous task async-await