V3231. Async method returning 'void' throws an exception. Callers will not be able to catch this exception. Consider replacing the return type with 'Task'.
Анализатор обнаружил метод с модификатором async и типом возвращаемого значения void, внутри которого выбрасывается исключение. Исключения, возникающие в таких методах, не могут быть перехвачены или обработаны вызывающим кодом, поскольку метод не возвращает объект типа Task, который используется для ожидания завершения асинхронной операции и обработки исключений.
Согласно рекомендациям такие методы не следует использовать за пределами обработчиков событий. Это связано с тем, что их невозможно использовать с await, контролировать их завершение или обрабатывать возникающие в них исключения в вызывающем контексте. В результате необработанные исключения могут привести к аварийному завершению процесса.
Рассмотрим пример:
async void LoadDataAsync(string data)
{
await Task.Delay(100);
if (data == null)
throw new InvalidOperationException("Data loading error.");
....
}
void Start(string data)
{
try
{
LoadDataAsync(data);
}
catch
{
....
}
}
Исключение, которое выбрасывается в методе LoadDataAsync, не будет отловлено в методе Start, т. к. LoadDataAsync — async-метод с типом возвращающего значения void.
Исправленный пример:
async Task LoadDataAsync(string data)
{
await Task.Delay(100);
if (data == null)
throw new InvalidOperationException("Data loading error.");
....
}
async Task Start(string data)
{
try
{
await LoadDataAsync(data);
}
catch
{
....
}
}
Теперь асинхронная операция представлена объектом Task. Это позволяет дождаться её завершения и обработать исключение в вызывающем контексте.
Данная диагностика классифицируется как: