Самые Частые Ошибки при Работе с async/await. Начало 1-4
1. Лишний async/await
Использование ключевых слов async/await приводит к неявному выделению памяти под конечный автомат, который отвечает за организацию асинхронных вызовов. Когда ожидаемое выражение является единственным или последним оператором в функции, его можно пропустить. Однако с этим есть несколько проблем, о которых вам следует знать.
❌ Неверно
async Task DoSomethingAsync(){
await Task.Yield();
}
✅ ВерноTask DoSomethingAsync() {
return Task.Yield();
}
2. Вызов синхронного метода внутри асинхронного методаЕсли мы используем асинхронный код, мы всегда должны использовать асинхронные методы, если они существуют. Многие API предлагают асинхронные аналоги своих хорошо известных синхронных методов.
❌ Неверно
async Task DoAsync(Stream file, byte[] buffer) {
file.Read(buffer, 0, 10);
}
✅ Верноasync Task DoAsync(Stream file, byte[] buffer) {
await file.ReadAsync(buffer, 0, 10);
}
3. Использование async voidЕсть две причины, по которым
async void вреден:- Вызывающий код не может ожидать метод
async void.- Невозможно обработать исключение, вызванное этим методом. Если возникает исключение, ваш процесс падает!
Вы всегда должны использовать
async Task вместо async void, если только это не обработчик событий, но тогда вы должны гарантировать себе, что метод не выбросит исключения.❌ Неверно
async void DoSomethingAsync() {
await Task.Yield();
}
✅ Верноasync Task DoSomethingAsync() {
await Task.Yield();
}
4. Неподдерживаемые асинхронные делегатыЕсли передать асинхронную лямбда-функцию в качестве аргумента типа
Action, компилятор сгенерирует метод async void, недостатки которого были описаны выше. Есть два решения этой проблемы:- изменить тип параметра с
Action на Func<Task>, - реализовать этот делегат синхронно.
Стоит отметить, что некоторые API-интерфейсы уже предоставляют аналоги своих методов, которые принимают
Func<Task>.
void DoSomething() {
Callback(async() => {
await Task.Yield();
});
}
❌ Неверноvoid Callback(Action action){…}
✅ Верноvoid Callback(Func<Task> action){…}
Продолжение следует…Источник: https://cezarypiatek.github.io/post/async-analyzers-p1/