асинхронное ожидание для виртуального метода

2

В нашем старом синхронном приложении в нашем базовом классе было следующее:

public virtual bool ShouldSomethingHappen() => false;

Итак, идея заключается в том, что в производном классе в БД может быть вызван вызов, чтобы определить, должно ли что-то произойти.

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

public virtual async Task<bool> ShouldSomethingHappen()
{
    await Task.Yield();
    return false;
}

Казалось, что это хорошо работает при запуске приложения, но оно нарушило наши интеграционные тесты (где у нас много ожидаемых вызовов).... мы не могли понять, почему.

Но, изменив это на следующее, исправлена проблема:

public virtual async Task<bool> ShouldSomethingHappen() => Task.FromResult(false);

Так технически, какая разница между этими двумя подходами?

  • 1
    Определение не нуждается в async которую можно было бы упростить для public virtual Task<bool> ShouldSomethingHappen() => Task.FromResult(false); , Если на самом деле ничего не ожидается, нет необходимости помечать вызов async
  • 0
    Имейте в виду - async не является частью подписи. Хорошо иметь простой виртуальный метод (не async ), который возвращает Task и некоторый производный тип может переопределить этот метод с помощью async реализации.
Теги:
async-await
task-parallel-library

1 ответ

2

Может быть, все, что было в ваших тестах интеграции после await Task.Yield() не предназначено для работы с другим потоком. Task.Yield() заставляет метод продолжать использовать остальную часть метода в другом потоке. Когда вы используете Task.FromResult вы возвращаете уже завершенную задачу. Вы просто возвращаете завершенную задачу, поэтому она все равно происходит в одном и том же потоке.

Вы можете проверить это, изменив Task.FromResult(false) на Task.FromResult(false).ConfigureAwait(false). await Task.Delay(n).ConfigureAwait(false)

  • 0
    Добавление .ConfigureAwait (false) не имеет никакого эффекта, но я думаю, что это определяет, будет ли исходный контекст упакован и выбран «следующим» потоком. Если Task.FromResult (...) эффективно синхронен, то это может не иметь никакого эффекта.
  • 0
    @DrGriff Да, это может быть так. Вы можете попробовать что-то вроде await Task.Delay(10).ConfigureAwait(false) просто для подтверждения.
Показать ещё 5 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню