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

标签 c# multithreading asynchronous async-await

在这段代码中:

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/

相关文章:

wpf - 使用函数开始调用?

c# - 使用 EntityFramework 的模式?

c# - 如何使用 ServiceController 远程控制 Windows 服务?

c# - 在 web.config 文件中使用授权时被重定向回登录屏幕

c# - 使用 WebBrowser Control 以编程方式登录网站时出现问题

c# - 如果可能的话,是否应该在软件组件内部避免使用线程?

java - 如何在 Java 中使用 TwoTuple 集合设置变量?

java - 如何正确使用Java Executor?

java - 时间密集型计算和 SWT

c# - 等待 100 毫秒以获取方法返回的数据 else throw exception