ded*_*cos 3 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!");
}
Run Code Online (Sandbox Code Playgroud)
如果调用ButtonClick,上述哪些方法实际上是在async/await生成的底线程池中并行执行的?
我的意思是,对于使用async/await的竞争条件,我应该关注什么?所有异步方法都必须在同一个调用者的线程中执行?我应该在可能的共享状态上使用互斥吗?如果是,我怎么能检测到共享状态对象是什么?
如果调用ButtonClick,上述哪些方法实际上是在async/await生成的底线程池中并行执行的?
只有Console.WriteLine在内Task.Run.
我的意思是,对于使用async/await的竞争条件,我应该关注什么?
我建议你先阅读我的async介绍,这解释了await实际的工作原理.
总之,async方法通常以串行异步方式编写.以此代码为例:
CodeBeforeAwait();
await SomeOtherMethodAsync();
CodeAfterAwait();
Run Code Online (Sandbox Code Playgroud)
你总是可以说CodeBeforeAwait先执行完成,然后SomeOtherMethodAsync调用.然后我们的方法将(异步)等待SomeOtherMethodAsync完成,并且只有在此之后才会CodeAfterAwait被调用.
所以它是串行异步的.它以串行的方式执行,就像你期望的那样,但也在该流程中使用异步点(the await).
现在,你不能说CodeBeforeAwait并且CodeAfterAwait将在同一个线程中执行,至少在没有更多上下文的情况下.await默认情况下将恢复当前SynchronizationContext(TaskScheduler如果没有SyncCtx 则恢复当前).因此,如果上面的示例方法在UI线程中执行,那么您将知道CodeBeforeAwait并且CodeAfterAwait将在UI线程上执行.但是,如果它是在没有上下文的情况下执行的(即,从后台线程或Console主线程执行),则CodeAfterAwait可以在不同的线程上运行.
请注意,即使方法的某些部分在不同的线程上运行,运行时也会在继续该方法之前设置任何障碍,因此不需要屏蔽变量访问.
另请注意,您的原始示例使用了Task.Run,它明确地将工作放在线程池上.这与async/ 完全不同await,你肯定必须将其视为多线程.
我应该在可能的共享状态上使用互斥吗?
是.例如,如果您的代码使用Task.Run,那么您需要将其视为单独的线程.(请注意,使用await,这是一个很多更容易不与其他线程在所有共享状态-如果你能保持你的后台任务纯洁,所以他们可以很容易与工作).
如果是,我怎么能检测到共享状态对象是什么?
与任何其他类型的多线程代码相同的答案:代码检查.