Исключения | Exception 
async Task ActionAsyncЕсли внутри метода возникнет исключение, то будет возвращен Task с исключением
Task ActionAsync

Если внутри метода возникнет исключение, то оно будет проброшено наверх напрямую.

Если мы хотим сохранить общее поведение, то необходимо использовать конструкцию:
try
{
   return Task.CompletedTask;
}
catch (Exception ex)
{
   return Task.FromException(ex);
}

AsyncLocal
async Task ActionAsyncВ случае, если внутри метода будет задано значение AsyncLocal контейнера, то при выходе из метода оно будет сброшено на родительское значение.
Task ActionAsyncВ случае, если внутри метода будет задано значение AsyncLocal контейнера, то при выходе из метода оно не будет сброшено.
Выполнение кода
1)var tasks = Enumerable
    .Range(0, 10)
    .Select(
       async e => {
            action1();
           await Task.Delay(TimeSpan.FromSeconds(10));
            action2();
        }
    )
    .ToArray();
await Task.WhenAll(tasks);
action1 будут выполнены одним потоком (который вызвал Enumarable) последовательно друг за другом (без какого-либо параллелизма). После этого происходит асинхронное ожидание и прерывание потока исполнения.
action2 будет выполнено после ожидания при этом поток его выполнения зависит от параметров SynchronizationContext | Контекст синхронизации окружения (при этом могут исполняться параллельно друг другу в разных потоках.
2)var tasks = Enumerable
    .Range(0, 10)
    .Select(
        e => Task.Run(
           async () => {
                action1();
               await Task.Delay(TimeSpan.FromSeconds(10));
                action2();
            }
            )
    )
    .ToArray();
await Task.WhenAll(tasks);
При таком вызове  на каждый отдельный элемент будет запущена отдельная задача через планировщик. Действия будут выполняться параллельно друг другу (в том числе и action1) в разных потоках.
   

 

 

Теги:
Создал(а) Alexandr Fokin 2024/01/09 19:24