Based on IHttpActionResult I created a base class (simplified):
public abstract class BaseHttpActionResult<T> : IHttpActionResult
{
protected readonly HttpRequestMessage Request;
internal abstract Task<T> ExecuteAsync();
protected BaseHttpActionResult(HttpRequestMessage request)
{
Request = request;
}
public async Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
try
{
T data = await ExecuteAsync();
return Request.CreateResponse(HttpStatusCode.OK, data);
}
catch (Exception ex)
{
HttpStatusCode statusCode;
if (ex is UnauthorizedAccessException)
{
// 403
statusCode = HttpStatusCode.Forbidden;
}
else if (ex is ObjectNotFoundException)
{
// 404
statusCode = HttpStatusCode.NotFound;
}
else if (ex is DbUpdateConcurrencyException)
{
// 409
statusCode = HttpStatusCode.Conflict;
}
else
{
statusCode = HttpStatusCode.InternalServerError;
}
return Request.CreateErrorResponse(statusCode,
$"{GetType().Name} - {ex.GetType().Name}: '{ex.Message}'",
ex);
}
}
}
One simple implementation of this could be like this:
public class SampleResult : BaseHttpActionResult<string>
{
private readonly IDoAsyncStuffService service;
public SampleResult(IDoAsyncStuffService service, HttpRequestMessage request) : base(request)
{
this.service = service;
}
internal override async Task<string> ExecuteAsync()
{
return await service.GetSomethingAsync();
}
}
And then the usage in the controller:
[HttpGet]
[Route(RouteConfig.Get.Sample)]
public SampleResult GetSampleResult()
{
return new SampleResult(service, Request);
}
However as you can see my controller method now lacks the async keyword and also it returns only a SampleResult instead of a Task<SampleResult>.
So my question is now:
Is still everything executed async, even though my controller method is not declared as such and does not return a task?
Or do I need to do something differently?
Despite its appearance, async is an implementation detail rather than part of the signature of the method. It's just a particular means for you to author a function that returns a Task that represents ongoing work.
It's perfectly possible to author a method that returns a Task that represents ongoing work without using the async and await keywords. Such a method is indistinguishable from your method, so far as the caller is concerned.
So, yes, when your ExecuteAsync method is called it will be as async as it is capable of being.
The GetSampleResult itself will not be executed async because there is nothing async in it, but when executing the result, that will execute asynchronously as expected.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With