Имитация асинхронного (Async) Deadlock
Версия 1.5 от Alexandr Fokin на 2023/01/11 14:50
[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
);
}
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
);
}