Информация об изменениях

Сообщение Re[3]: Почему будет deadlock? от 20.01.2020 15:26

Изменено 20.01.2020 15:32 RushDevion

Re[3]: Почему будет deadlock?
S>Это понятно, но почему в исходном случае deadlock? Почему все на одном стеке? Как это можно понять не запуская код, т.к. данная ситуация стабильно вопроизводится, следовательно есть
S>какая-то неявная особенность.

async void Test()
{
    var tcs = new TaskCompletionSource<int>();
    var task = Task.Factory.StartNew(() =>
    {
        Thread.Sleep(1000);
        tcs.SetResult(10); // Таска (из task completion source) завершилась и синхронно запустился сontinuation (3)
        // task ждет завершения continuation (1) (deadlock)
        Console.WriteLine("here3");
    });


    // await tcs.Task раскроется во что-то типа
    tcs.Task.GetAwaiter().OnCompleted(() => /* (1) continuation */
    {
        // continuation ждет завершения task (deadlock)
        task.Wait();
    });
}

// Если написать
var tcs = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
// То continuation будет запускаться на другом потоке и дедлока не будет
Re[3]: Почему будет deadlock?
S>Это понятно, но почему в исходном случае deadlock? Почему все на одном стеке? Как это можно понять не запуская код, т.к. данная ситуация стабильно вопроизводится, следовательно есть
S>какая-то неявная особенность.

async void Test()
{
    var tcs = new TaskCompletionSource<int>();
    var task = Task.Factory.StartNew(() =>
    {
        Thread.Sleep(1000);
        tcs.SetResult(10); // Таска (из task completion source) завершилась и синхронно запустился сontinuation (1)
        // task ждет завершения continuation (1) (deadlock)
        Console.WriteLine("here3");
    });


    // await tcs.Task раскроется во что-то типа
    tcs.Task.GetAwaiter().OnCompleted(() => /* (1) continuation */
    {
        // continuation ждет завершения task (deadlock)
        task.Wait();
    });
}

// Если написать
var tcs = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
// То continuation будет запускаться на другом потоке и дедлока не будет