Вернуть задачу или ждать и ConfigureAwait (false)

Предположим, что у вас есть библиотека услуг с таким методом

public async Task<Person> GetPersonAsync(Guid id) {
  return await GetFromDbAsync<Person>(id);
}

Следуя рекомендациям для SynchronizationContext, лучше использовать

public async Task<Person> GetPersonAsync(Guid id) {
  return await GetFromDbAsync<Person>(id).ConfigureAwait(false);
}

Но когда у вас есть только одна операция (я думаю), лучше вернуть задачу непосредственно. См. В конце метода async я должен вернуться или ждать?

public Task<Person> GetPersonAsync(Guid id) {
  return GetFromDbAsync<Person>(id);
}

В этом последнем случае вы не можете использовать ConfigureAwait (false), потому что этот метод не ожидается.

Какое наилучшее решение (и почему)?

Ответ 1

Каждый вариант имеет свою специфику, отметьте этот и этот. Если вы их понимаете, вы можете решить, какой из них лучше для вас.

Таким образом, решение, которое возвращает задачу непосредственно, не захватывает SynchronizationContext?

Это не задача, которая захватывает текущий контекст синхронизации. Он TaskAwaiter.OnCompleted (или ConfiguredTaskAwaitable.OnCompleted, в случае ConfigureAwait), который косвенно вызывается кодом, сгенерированным компилятором С#, как часть инструкции await для задачи.

Итак, если вы не используете await, вы не должны беспокоиться о захвате SynchronizationContext, это не волшебство происходит само по себе. Это, вероятно, делает третий вариант наиболее благоприятным, но помните о его режиме распространения исключений.