小编Dmi*_*uev的帖子

对同一个任务进行多次等待可能会导致阻塞

在同一个任务上使用多个等待应该小心。我在尝试使用BlockingCollection.GetConsumingEnumerable()方法时遇到过这种情况。最终得到这个简化的测试。

class TestTwoAwaiters
{
    public void Test()
    {
        var t = Task.Delay(1000).ContinueWith(_ => Utils.WriteLine("task complete"));
        var w1 = FirstAwaiter(t);
        var w2 = SecondAwaiter(t);

        Task.WaitAll(w1, w2);
    }

    private async Task FirstAwaiter(Task t)
    {
        await t;
        //await t.ContinueWith(_ => { });
        Utils.WriteLine("first wait complete");
        Task.Delay(3000).Wait(); // execute blocking operation
    }

    private async Task SecondAwaiter(Task t)
    {
        await t;
        Utils.WriteLine("second wait complete");
        Task.Delay(3000).Wait(); // execute blocking operation
    }

}
Run Code Online (Sandbox Code Playgroud)

我认为这里的问题是任务的延续将因此在一个线程上执行订阅者。如果一个等待者执行阻塞操作(例如从 中产生BlockingCollection.GetConsumingEnumerable()),它将阻塞其他等待者并且他们无法继续他们的工作。ContinueWith()我认为一个可能的解决方案是在等待任务之前调用。它将把延续分成两部分,并且阻塞操作将在新线程上执行。

有人可以确认或反驳多次等待任务的可能性吗?如果这种情况很常见,那么绕过阻塞的正确方法是什么?

c# deadlock async-await

6
推荐指数
1
解决办法
6124
查看次数

标签 统计

async-await ×1

c# ×1

deadlock ×1