gpt4 book ai didi

c# - 等待和预防死锁 - 澄清?

转载 作者:太空狗 更新时间:2023-10-29 21:27:27 33 4
gpt4 key购买 nike

我读了this article关于 Task.ConfigureAwait,它有助于防止异步代码中的死锁。

看看这段代码:(我知道我不应该做 .Result ,但这是问题的一部分)

private void Button_Click(object sender, RoutedEventArgs e)
{
string result = GetPageStatus().Result;
Textbox.Text = result;
}
public async Task<string> GetPageStatus()
{
using (var httpClient = new HttpClient())
{
var response = await httpClient.GetAsync("http://www.google.com");
return response.StatusCode.ToString();
}
}

这将导致死锁,因为:

  1. .Result - 操作将在等待异步操作完成时阻塞当前线程(即 UI 线程)。

  2. 网络调用完成后,它将尝试继续执行 response.StatusCode.ToString() - 在捕获的上下文中的方法。 (被阻止 - 因此出现死锁)。

一个解决方案是使用:

var response = await httpClient.GetAsync("http://www.google.com").ConfigureAwait(false);

但其他解决方案是一直异步(不阻塞):

/*1*/   private async void Button_Click(object sender, RoutedEventArgs e)
/*2*/ {
/*3*/ string result = await GetPageStatus();
/*4*/ Textbox.Text = result;
/*5*/ }
/*6*/ public async Task<string> GetPageStatus()
/*7*/ {
/*8*/ using (var httpClient = new HttpClient())
/*9*/ {
/*10*/ var response = await httpClient.GetAsync("http://www.google.com");
/*11*/ return response.StatusCode.ToString();
/*12*/ }
/*13*/ }

问题:

(我试图了解这段代码如何帮助解决问题 - 通过上下文 POV)。

  1. #3 行和 #10 行是否捕获了不同的上下文?

  2. 我认为的流动方式是否正确:

    • 第 3 行调用了第 6 行(后者调用了第 10 行),发现它尚未完成,因此它等待(#3 的捕获上下文 = UI 线程)。

    • 稍后,第 10 行捕获另一个上下文(我将其称为 newContext)完成后,它返回到“newContext”,然后释放 UI 上下文(线程)。

我说的对吗?

  1. 可视化:(这是正确的流程吗?)

Code execution flow

最佳答案

Does line #3 and line #10 captures different contexts ?

从您的代码来看,没有。它们都将捕获相同的 UI 同步上下文,因为您不使用 ConfigureAwait(false) 这会阻止将延续编码回 UI 上下文。

Am I right regarding the way of flow as I think it is :

line #3 calls #6 (which calls #10) and sees that it didnt finish yet , so it awaits ( captured context for #3= UI thread).

Later on , line #10 capture another context ( I will call it newContext) after it finishes , it is back to "newContext" and then releases the UI context(thread).

差不多。您的通话中没有创建“新上下文”。它始终是相同的 UI 同步上下文。例如,如果您有两个异步调用一个接一个,当一个调用使用 ConfigureAwait(false) 时,第二个调用将继续在线程池线程上执行。

至于您的可视化,它确实正确地捕获了代码的执行流程。

关于c# - 等待和预防死锁 - 澄清?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27636869/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com