Должен ли эндпоинт контроллера Asp.Net быть асинхронным

Есть мнение что эндпоинт контроллера в ASP.NET API должен быть асинхронным в любом случае, но что делать если в нем нет вызова await ?

  1. Вариант оставить async но тогда будет предупреждение CS1998
[HttpGet]
public async Task<ActionResult<string>> GetTaskResult()
{
    //CS1998 Нет await
    var result = GetResSync();
    return Ok(result);
}
  1. Вариант с возвратом Task
[HttpGet]
public Task<ActionResult<string>> GetTaskResult()
{
    var result = GetResSync();
    ActionResult<string> actionResult = Ok(result);
    return Task.FromResult(actionResult);
}
  1. Вариант сделать синхронно. UPD Действительно, оба примера синхронны как отметил EvgeniyZ. Скажем вариант без оборачивания в Task
[HttpGet]
public ActionResult<string> GetResult()
{
    var result = GetResSync();
    ActionResult<string> actionResult = Ok(result);
    return actionResult;
}

Какой вариант более предпочтительный?


Ответы (1 шт):

Автор решения: aepot

В асинхронности есть смысл тогда, когда используются асинхронные операции. Ни в одном из предложенных вариантов у вас их нет.

Следовательно наиболее оптимальным выглядит синхронный вариант.

Ключевое слово async не делает метод асинхронным. Вот примеры

Синхронный метод (метод, всегда завершающийся синхронно)

private async Task Method1()
{
    Thread.Sleep(100);
}

Асинхронный метод (метод, возвращающий незавешенный Task)

private Task Method2()
{
    return Task.Delay(100);
}

Первый синхронный потому что в 100% случаев Task, который он вернёт, уже будет завершён. То есть метод завершится синхронно. Не нужно писать методы с асинхронной сигнатурой, но выполняющиеся синхронно, это ошибка.

Второй асинхронный, потому что вернёт незавершённый Task, чем инициирует асинхронное ожидание, если написать await Method2().

Поэтому нет смысла использовать async без await.

Что касается Task.FromResult, это полезно, когда вы вынуждены вернуть Task, например при реализации интерфейса или наследовании класса, но асинхронной работы в методе неоткуда взять или не требуется. В вашем конкретном случае есть синхронный вариант, поэтому использовать Task.FromResult нет смысла.

→ Ссылка