Console.WriteLine("Hello!")); } public-6ren">
gpt4 book ai didi

c# - "multi-threadedly"在 async/await 模式下实际上执行了什么代码?

转载 作者:行者123 更新时间:2023-11-30 13:55:09 25 4
gpt4 key购买 nike

在这段代码中:

public async Task v_task()
{
await Task.Run(() => Console.WriteLine("Hello!"));
}

public async void v1()
{
await v_task();
// some other actions...
}

public void ButtonClick()
{
v1();

Console.WriteLine("Hi!");
}

如果调用 ButtonClick,上述哪些方法实际上是在 async/await 生成的底层线程池中并行执行的?

我的意思是,对于使用 async/await 的竞争条件,我应该担心什么?所有异步方法都必须在同一个调用者的线程中执行吗?我应该在可能的共享状态上使用互斥量吗?如果是,我如何检测共享状态对象是什么?

最佳答案

Which methods above are actually executed in parallel in the async/await generated lower thread pool if ButtonClick is called?

只有 Task.Run 中的 Console.WriteLine

I mean, what should be my concerns about race conditions working with async/await?

我建议您先阅读我的 async intro ,它解释了 await 的实际工作原理。

总而言之,async 方法通常以串行异步 方式编写。以这段代码为例:

CodeBeforeAwait();
await SomeOtherMethodAsync();
CodeAfterAwait();

您总是可以说 CodeBeforeAwait 将首先执行完成,然后调用 SomeOtherMethodAsync。然后我们的方法将(异步地)等待 SomeOtherMethodAsync 完成,只有在那之后才会调用 CodeAfterAwait

所以它是串行异步的。它以串行方式执行,就像您期望的那样,但在该流程中也有一个异步点(await)。

现在,您不能CodeBeforeAwaitCodeAfterAwait 将在同一个线程中执行,至少在没有更多上下文的情况下是这样。 await 默认会在当前的 SynchronizationContext 中恢复(如果没有 SyncCtx,则在当前的 TaskScheduler 中恢复)。因此,如果上面的示例方法是在 UI 线程中执行的,那么您就会知道 CodeBeforeAwaitCodeAfterAwait 都将在 UI 线程中执行。但是,如果它是在没有上下文的情况下执行的(即从后台线程或控制台主线程执行),则 CodeAfterAwait 可能会在不同的线程上运行。

请注意,即使方法的某些部分在不同的线程上运行,运行时也会在继续该方法之前负责设置任何障碍,因此无需围绕变量访问设置障碍。

另请注意,您的原始示例使用 Task.Run,它明确地将工作放在线程池上。这与 async/await 完全不同,您肯定必须将其视为多线程。

Should I use mutex on possible shared state?

是的。例如,如果您的代码使用 Task.Run,那么您需要将其视为一个单独的线程。 (请注意,使用 await很多更容易完全不与其他线程共享状态 - 如果您可以保持后台任务纯净,它们会更容易工作与)。

If yes, how could I detect what are the shared state objects?

与任何其他类型的多线程代码相同的答案:代码检查。

关于c# - "multi-threadedly"在 async/await 模式下实际上执行了什么代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36690980/

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