I am currently implementing System.Web.Http.IActionFilterthat calls an internal service to determine if the current request can continue. The problem I am facing is returning Task<T1>based on the piece of logic enclosed in Task<T2>.
An example may help.
The internal service API is implemented using Tasks. The logic is trivial using .NET 4.5 async / wait:
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();
}
However, more complicated with the old task API in .NET 4.0 ;
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);
}
return continuation().Result;
});
}
The difficult part arises when authentication is successful - I want to wait for the task returned by the continue function.
.NET 4.0 , , continuation(), , API continuation(), .
: .NET 4.0?
API , , .
: , 4.0 - ASP.NET, HttpContext.Current . ...
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();
}