Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么TPL在与continueOnCapturedContext一起使用Wait时不会死锁:true?_C#_Asynchronous_Task Parallel Library_Deadlock - Fatal编程技术网

C# 为什么TPL在与continueOnCapturedContext一起使用Wait时不会死锁:true?

C# 为什么TPL在与continueOnCapturedContext一起使用Wait时不会死锁:true?,c#,asynchronous,task-parallel-library,deadlock,C#,Asynchronous,Task Parallel Library,Deadlock,这个问题不同于其他问题。这个问题涉及一个案例,其中(据称)Wait导致死锁,而.Wait没有。这个问题正好相反。此外,问题和回答者在另一个问题上存在分歧,因此根本无法回答我的问题 这会导致ASP.Net请求上下文中出现死锁: protected void TestBtnClick(object sender, EventArgs e) { DoSomethingAsync() .Wait(); } private asy

这个问题不同于其他问题。这个问题涉及一个案例,其中(据称)Wait导致死锁,而.Wait没有。这个问题正好相反。此外,问题和回答者在另一个问题上存在分歧,因此根本无法回答我的问题

这会导致ASP.Net请求上下文中出现死锁:

    protected void TestBtnClick(object sender, EventArgs e)
    {
        DoSomethingAsync()
            .Wait();
    }


    private async Task DoSomethingAsync()
    {
        await Task.Delay(2000)
                  .ConfigureAwait(continueOnCapturedContext: true);
    }
我的理解是,第一个调用方法正在等待整理原始同步上下文,然后被调用的方法也在等待整理原始上下文,从而导致死锁

如果是这种情况,为什么下面的操作不会导致死锁

    protected async void TestBtnClickAsync(object sender, EventArgs e)
    {
        await DoSomethingAsync()
            // ****** DIFFERENCE IS HERE: ******
            .ConfigureAwait(continueOnCapturedContext: true);
    }


    private async Task DoSomethingAsync()
    {
        await Task.Delay(2000)
                  .ConfigureAwait(continueOnCapturedContext: true);
    }

请注意,这两个异步调用都显式地请求在原始同步上下文上继续。

因为在第一个代码块中,您显式地调用了
Wait()
。这会阻止线程的执行,因此无法在该线程上安排继续。线程永远不会返回池,它坐在那里等待一个信号继续执行,它永远不会收到这个信号,因为该信号将来自等待在等待线程上调度的延续


在第二个块中,
Wait
关键字将线程返回到池中,以便以后当线程空闲时(不处理其他请求),可以在该线程上再次安排继续操作。

因为在第一个代码块中,您显式地调用了
Wait()
。这会阻止线程的执行,因此无法在该线程上安排继续。线程永远不会返回池,它坐在那里等待一个信号继续执行,它永远不会收到这个信号,因为该信号将来自等待在等待线程上调度的延续


在第二个块中,
Wait
关键字将线程返回到池中,以便以后当线程空闲时(不处理其他请求),可以在该线程上再次安排继续操作。

因为在第一个代码块中,您显式地调用了
Wait()
。这会阻止线程的执行,因此无法在该线程上安排继续。线程永远不会返回池,它坐在那里等待一个信号继续执行,它永远不会收到这个信号,因为该信号将来自等待在等待线程上调度的延续


在第二个块中,
Wait
关键字将线程返回到池中,以便以后当线程空闲时(不处理其他请求),可以在该线程上再次安排继续操作。

因为在第一个代码块中,您显式地调用了
Wait()
。这会阻止线程的执行,因此无法在该线程上安排继续。线程永远不会返回池,它坐在那里等待一个信号继续执行,它永远不会收到这个信号,因为该信号将来自等待在等待线程上调度的延续


在第二个块中,
await
关键字将线程返回池中,以便以后当线程空闲时(不处理其他请求),可以在该线程上再次安排继续操作。

在同一上下文中恢复大量等待的原因是,它们允许其他线程同时使用它

想象一下,在线程上执行就像那些“不得不握着棍子说话”组中的棍子一样。你的第一个例子是,一个人问某人一个问题,然后拒绝放弃棍子,直到问题得到回答。但另一个人在拿到棍子之前无法回答!显然这里会有问题

在你的第二个例子中,这个人问了某人一个问题,在给出答案后要求别人还给他棍子,然后放弃棍子。一路上可能会有一些无关的闲聊,但至少这个问题会得到回答。好多了


(请注意,默认情况下,在捕获的上下文上继续操作,因此您不会通过明确请求来更改任何内容。)

在同一上下文上恢复大量等待的原因是,它们允许其他人同时使用它

想象一下,在线程上执行就像那些“不得不握着棍子说话”组中的棍子一样。你的第一个例子是,一个人问某人一个问题,然后拒绝放弃棍子,直到问题得到回答。但另一个人在拿到棍子之前无法回答!显然这里会有问题

在你的第二个例子中,这个人问了某人一个问题,在给出答案后要求别人还给他棍子,然后放弃棍子。一路上可能会有一些无关的闲聊,但至少这个问题会得到回答。好多了


(请注意,默认情况下,在捕获的上下文上继续操作,因此您不会通过明确请求来更改任何内容。)

在同一上下文上恢复大量等待的原因是,它们允许其他人同时使用它

想象一下,在线程上执行就像那些“不得不握着棍子说话”组中的棍子一样。你的第一个例子是,一个人问某人一个问题,然后拒绝放弃棍子,直到问题得到回答。但另一个人在拿到棍子之前无法回答!显然这里会有问题

在你的第二个例子中,这个人问了某人一个问题,在给出答案后要求别人还给他棍子,然后放弃棍子。一路上可能会有一些无关的闲聊,但至少这个问题会得到回答。好多了

(请注意,默认情况下会继续捕获上下文,因此不会更改任何内容。)