实际以异步/等待模式“多线程”执行的代码是什么?

Andresantacruz

在此代码中:

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生成的较低线程池中并行执行?

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

斯蒂芬·克莱里

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

Console.WriteLine在内Task.Run

我的意思是,我对使用异步/等待的竞争条件应该有什么关注?

我建议您先阅读我的async介绍,它介绍了await实际的工作方式。

总之,async方法通常以串行异步方式编写以下面的代码为例:

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

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

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

现在,您不能这么说,CodeBeforeAwait并且CodeAfterAwait将在同一线程中执行,至少在没有更多上下文的情况下如此。await默认情况下将在当前SynchronizationContextTaskScheduler如果没有SyncCtx ,则在当前)中恢复因此,如果上面的示例方法是在UI线程中执行的,那么您将知道这一点,CodeBeforeAwait并且CodeAfterAwait都将在UI线程上执行。但是,如果执行时没有上下文(即从后台线程或控制台主线程),则CodeAfterAwait可能在其他线程上运行。

请注意,即使方法的某些部分在不同的线程上运行,运行时也会在继续执行该方法之前将所有的障碍放置在适当的位置,因此无需在变量访问方面设障碍。

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

我应该在可能的共享状态上使用互斥锁吗?

是。例如,如果您的代码使用Task.Run,则需要将其视为一个单独的线程。(注:在await,这是一个很多更容易不共享状态都与其他线程-如果你能保持你的后台任务纯洁,他们更容易与工作)。

如果是,我如何检测共享状态对象是什么?

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章