Ответ 1
Должен ли я использовать async в библиотеке?
Все зависит. Если вы собираетесь использовать асинхронную парадигму программирования, тогда ответ будет "да", ключевые слова async
и await
необходимы большую часть времени. Скорее всего, вам понадобится использовать async/await
. Это связано с тем, что в большинстве ситуаций было бы трудно использовать только Task
и Task<T>
, так как вам, скорее всего, придется рассуждать о результатах операций async, которые вы вызываете.
Кроме того, на основе вашего вопроса кажется, что у вас может быть некоторая путаница в отношении самих ключевых слов и их отношении к типам Task
и Task<T>
. Позвольте мне уточнить это для вас.
Ключевое слово async
позволяет использовать метод await
. Лучшая практика заключается в том, чтобы все методы async возвращали либо Task
, либо Task<T>
, если вы не можете (например, обработчик события нажатия кнопки, как вы показали выше).
Методы, возвращающие Task
или Task<T>
, представляют асинхронные операции. Когда вы находитесь в библиотеке, рекомендуется использовать .ConfigureAwait(false)
по причинам, описанным ниже здесь. Кроме того, я всегда указываю людям на эту подробную статью по этому вопросу.
Чтобы дифференцировать два подхода в вашем вопросе:
В приведенном ниже методе возвращается a Task<SignResponse>
. Это асинхронная операция, которая представляет работу для входа. Метод может быть вызван вызывающим абонентом для получения SignResponse
.
private Task<SignResponse> GetSignDataAsync(SigningRequestType request)
{
return _service.SignAsync(request);
}
Аналогично, эта версия делает то же самое... за исключением того, что ключевые слова async/await
не нужны. Причина, по которой они не нужны, заключается в том, что самому методу не нужно использовать SignResponse
, и поэтому он может просто вернуть Task<SignResponse>
, как показано выше. И, как вы указали в своем вопросе, действительно существует штраф, если вы используете ключевые слова async/await
, когда они не нужны. При этом добавляется дополнительный шаг конечного автомата, так как результат получается, так как его ожидали.
private async Task<SignResponse> GetSignDataAsync(SigningRequestType request)
{
return await _service.SignAsync(request).ConfigureAwait(false);
}
Наконец, если вам нужно было обосновать ответ, вы можете использовать вышеупомянутые ключевые слова, чтобы сделать это следующим образом:
private async Task<SignResponse> GetSignDataAsync(SigningRequestType request)
{
var result = await _service.SignAsync(request).ConfigureAwait(false);
if (result.SomeProperty == SomethingWeCareToCheck)
{
_log.Log("Wow, this was un-expected...");
}
return result;
}