Сценарии - Имитация асинхронного (Async) Deadlock

Page / - Изменено Alexandr Fokin в 2024/03/23 16:50

Имитация асинхронного (Async) Deadlock

Изменено Alexandr Fokin

в 2024/03/23 16:50

Оглавление

В данном примере мы имитируем ограничение на использование одного потока (которые возникает в некоторых типах приложений, SynchronizationContext | Контекст синхронизации). После этого мы блокируем поток синхронным ожидаем, из-за чего асинхронная задача не может выполнить продолжение (continuation), т.к. она тоже запланирована на выполнение в этом (заблокированном) потоке.
Асинхронность. Async Await Проблемы
Task Factory SynchronizationContext | Контекст синхронизации
[TestMethod] public async Task AsyncDeadlockTest1Async() { var delay = TimeSpan.FromMilliseconds(100); var delay2 = TimeSpan.FromMilliseconds(500); async Task TestMethodAsync() { await Task.Delay(delay); } ConcurrentExclusiveSchedulerPair scheduler = new ConcurrentExclusiveSchedulerPair(); TaskFactory factory = new TaskFactory(scheduler: scheduler.ExclusiveScheduler); CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); AsyncAutoResetEvent startLock = new AsyncAutoResetEvent(set: false); var task = factory.StartNew( () => { startLock.Set(); var testTask = TestMethodAsync(); //Deadlock testTask.Wait( cancellationTokenSource.Token ); NotCorrectActionError.Throw("Данный код нет должен выплняться из-за Deadlock"); //Аналогичено, но без токена //testTask // .GetAwaiter() // .GetResult(); //NotCorrectActionError.Throw("Данный код нет должен выплняться из-за Deadlock"); } ); await startLock.WaitAsync(); cancellationTokenSource.CancelAfter(delay2); await Assert.ThrowsExceptionAsync<OperationCanceledException>( async () => await task ); }