Async Task выдает предупреждение, (без) Async Task выдает ошибку

Это, вероятно, более тонкий вопрос, но у меня есть следующий метод внутри класса ViewComponent

public async Task<IViewComponentResult> InvokeAsync()
{
    return View();
}

но имя InvokeAsync подчеркнуто и дает следующее предупреждение

В этом асинхронном методе отсутствуют операторы ожидания, и он будет работать синхронно. Рассмотрите возможность использования оператора await для ожидания неблокирующих вызовов API или await Task.Run (...) для выполнения работы, связанной с процессором, в фоновом потоке.

но если я попытаюсь удалить async из метода, тогда return View () будет подчеркнут красным и выдаст следующую ошибку

'Microsoft.AspNetCore.Mvc.ViewComponents.ViewViewComponentResult' в 'System.Threading.Tasks.Task' MVCStateManagement

Итак, мой вопрос: какой подход мне выбрать? Разрешить асинхронность без предупреждения, или есть обходной путь / исправление для этого предупреждения? Это так сильно повлияло на мой проект?

Спасибо!


person Vlădel    schedule 22.08.2018    source источник
comment
Я следовал этому руководству docs.microsoft.com/en-us/aspnet/core/mvc/views/, поэтому он определен так.   -  person Vlădel    schedule 22.08.2018
comment
@AluanHaddad: Хороший вопрос. Смотрите мой ответ.   -  person mm8    schedule 22.08.2018
comment
Причина, по которой он асинхронный в этом руководстве, заключается в том, что в учебнике он вызывает метод async: var items = await GetItemsAsync (maxPriority, isDone) ;. Если вы не вызываете асинхронный метод в своем коде, то нет причин, чтобы ваш метод был асинхронным.   -  person TheSoftwareJedi    schedule 22.08.2018


Ответы (3)


Непонятно, почему метод был определен как метод async, который изначально возвращает Task<IViewComponentResult>.

Поскольку метод кажется действительно синхронным и просто возвращает представление, вам, вероятно, следует определить его следующим образом:

public IViewComponentResult Invoke()
{
    return View();
}

Синхронный метод не становится асинхронным волшебным образом только потому, что вы добавляете к нему ключевое слово async.

Если вы реализуете интерфейс и не можете изменить сигнатуру метода, вы можете использовать метод Task.FromResult для возврата уже выполненной задачи (вам все равно следует удалить ключевое слово async):

public Task<IViewComponentResult> InvokeAsync()
{
    return Task.FromResult<IViewComponentResult>(View());
}
person mm8    schedule 22.08.2018
comment
@Immorality, кажется, ответил на 1 минуту быстрее, чем вы, но ваш ответ более подробный. Большое спасибо за ваше время и помощь. - person Vlădel; 22.08.2018

Метод работает с задачей ViewcomponentResult. Вы можете вызвать его без асинхронности, используя это:

public Task<IViewComponentResult> InvokeAsync()
{
  return Task.FromResult<IViewComponentResult>(View());
}

Ваше предупреждение больше не будет отображаться, и ваш код будет запущен. Вы также можете оставить это. Ни то, ни другое не повлияет на производительность вашего проекта.

person Immorality    schedule 22.08.2018
comment
Кажется, это правильный ответ. Спасибо за помощь. - person Vlădel; 22.08.2018
comment
Будьте добры, отметьте ответ как правильный! - person Immorality; 22.08.2018

Вам нужно удалить флаг async и Task<>. Просто верните IViewComponentResult.

Обычно вы возвращаете объект, завернутый в Task<>, когда выполняете асинхронную работу. Если вы этого не сделаете, это не имеет никакого смысла.

Из MSDN:

Класс Task представляет собой одну операцию, которая возвращает значение и обычно выполняется асинхронно. Объекты задач являются одним из центральных компонентов асинхронного шаблона на основе задач, впервые представленного в .NET Framework 4. Поскольку работа, выполняемая объектом задачи, обычно выполняется асинхронно в потоке пула потоков, а не синхронно в потоке основного приложения, вы может использовать свойство Status, а также свойства IsCanceled, IsCompleted и IsFaaled для определения состояния задачи. Чаще всего лямбда-выражение используется для указания работы, которую должна выполнить задача.

https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1?view=netframework-4.7.2

РЕДАКТИРОВАТЬ:

Вы также можете попробовать вернуться:

return Task.FromResult<IViewComponentResult>(View());
person NicoRiff    schedule 22.08.2018
comment
Если я попытаюсь удалить задачу ‹›, возвращая только IViewComponentResult, программа выйдет из строя с этим InvalidOperationException: метод InvokeAsync компонента представления MVCStateManagement.ViewComponents.LayoutHeaderViewComponent должен быть объявлен для возврата задачи ‹T›. - person Vlădel; 22.08.2018