System.Web.Http.IActionFilter
現在、現在のリクエストを続行できるかどうかを判断するために内部サービスを呼び出す を実装しています。私が抱えている問題は、Task<T1>
によってカプセル化されたロジックに基づいて を返すことですTask<T2>
。
例が役立つ場合があります。
内部サービス API は、タスクを使用して実装されます。ロジックは、.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;
});
}
難しいのは、認証チェックが成功したときです。その後、継続関数によって返されるタスクを待ちたいと思います。
continuation()
.NET 4.0 を使用すると、タスクの完了時に Tasks API にタスクを自動的に続行するように指示するのではなく、タスクの完了を待つときに明示的にブロックしたように見えcontinuation()
ます。
質問: これが .NET 4.0 でこの動作を実装する唯一の方法ですか?
十分に複雑な内部サービス API を考えると、他のタスクを待機しているタスクの数が急速に増加していることを簡単に確認できます。
編集: HttpContext.Current のような ASP.NET スレッド コンテキスト サービスで継続ラムダが実行されないため、上記の4.0コードも実行可能ではないようです。より良い実装は...
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();
}