C# 我的控制器方法是异步执行的吗?

C# 我的控制器方法是异步执行的吗?,c#,asynchronous,async-await,asp.net-web-api2,C#,Asynchronous,Async Await,Asp.net Web Api2,基于IHttpActionResultI创建了一个基类(简化): 但是,正如您所看到的,我的控制器方法现在缺少async关键字,而且它只返回SampleResult而不是任务 所以我现在的问题是: 即使我的控制器方法没有声明为异步,也不返回任务,所有的东西都是异步执行的吗 或者我需要做一些不同的事情吗?尽管它看起来很像,但是async是一个实现细节,而不是方法签名的一部分。这只是您编写函数的一种特殊方式,该函数返回表示正在进行的工作的任务 完全可以编写一个方法,返回表示正在进行的工作的Task,

基于
IHttpActionResult
I创建了一个基类(简化):

但是,正如您所看到的,我的控制器方法现在缺少
async
关键字,而且它只返回
SampleResult
而不是
任务

所以我现在的问题是:

即使我的控制器方法没有声明为异步,也不返回任务,所有的东西都是异步执行的吗


或者我需要做一些不同的事情吗?

尽管它看起来很像,但是
async
是一个实现细节,而不是方法签名的一部分。这只是您编写函数的一种特殊方式,该函数返回表示正在进行的工作的
任务

完全可以编写一个方法,返回表示正在进行的工作的
Task
,而不使用
async
wait
关键字。就调用方而言,这样的方法与您的方法是无法区分的


因此,是的,当调用
ExecuteAsync
方法时,它将尽可能异步。

GetSampleResult
本身不会异步执行,因为其中没有任何异步内容,但在执行结果时,它将按预期异步执行

控制器方法不是
async
并不重要,
ExecuteAsync
方法仍将异步执行


当一个请求传入时,ASP.NET将获取它的一个线程池线程并将其分配给该请求。当它遇到异步部分的代码请求时,线程将在异步调用进行时返回到线程池。当异步调用返回时,ASP.NET将获取其中一个线程池线程并将其重新分配给该请求。

好的,您的控制器方法根本不执行异步操作。它只是返回一个类的实例,只要你调用它的ExecuteAsync方法,它就会立即返回该类的实例。正如前面提到的其他人一样,显然该方法是执行的,甚至是异步的(因为它实现了
IHttpActionResult
),我想我误解了你的控制器到底是什么。虽然这一切都是真的,但是,它与公共SampleResult GetSampleResult()无关。
。这一个完全不是异步的。它返回提供异步API的类的实例。这是另一回事。我弄错了吗?是的,
GetSampleResult
本身是同步的(而且很琐碎),但是OP是建立在ASP.Net基础设施上的,返回一个
IHttpActionResult
,它似乎执行真正的工作,所以我把重点放在了似乎可以做大量工作而不是琐碎工作的方法上。我理解这一点。我只是想知道OP是否也意识到了这一点。或者他认为是“一种控制方法”。谢谢。您的解释很有道理,也证实了我自己的大部分想法。我只是想确保我所做的是正确的,并且我可以利用async/await的优点。有用的文章:
  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);
      }
    }
  }
  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();
    }
  }
[HttpGet]
[Route(RouteConfig.Get.Sample)]
public SampleResult GetSampleResult()
{
  return new SampleResult(service, Request);
}