Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are my controller methods executed async?

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?

like image 368
OschtärEi Avatar asked Sep 27 '26 11:09

OschtärEi


2 Answers

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.

like image 130
Damien_The_Unbeliever Avatar answered Sep 29 '26 00:09

Damien_The_Unbeliever


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.

like image 26
Titian Cernicova-Dragomir Avatar answered Sep 28 '26 23:09

Titian Cernicova-Dragomir



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!