async和await关键字不会导致创建其他线程吗?
我糊涂了。 一个或多个Task
如何在一个线程上并行运行? 我对并行性的理解显然是错误的。
MSDN的比特我无法理解:
async和await关键字不会导致创建其他线程。 异步方法不需要multithreading,因为异步方法不能在自己的线程上运行。 该方法在当前同步上下文上运行,并且仅在方法处于活动状态时才在线程上使用时间。
..和:
在启动任务和等待任务之间,您可以启动其他任务。 其他任务隐式并行运行,但不会创建其他线程。
它们并不是并行运行,而是轮流运行。 当正在运行的任务阻止进度时,它会将其状态和控制权存储到就绪任务中。 这是合作的多任务处理,而不是真正的并行性。
线程按照样本原理运行。 但是,我想强调几个关键的区别。
首先,仅仅因为async
/ await
不是OS线程:
- 任务不会看到不同的线程ID
- 当任务产生时,线程本地存储不会自动上下文切换。
其次,行为的差异:
-
async
/await
使用协作式多任务处理,Win32线程使用抢占式。 因此,所有阻塞操作必须使用async
/await
模型明确地产生控制。 因此,您可以通过阻止调用未编写为yield的函数来阻止整个线程及其所有任务。 - 任务不会在多处理系统上并行执行。 由于重新引入被控制,这使得保持数据结构一致性变得更加容易。
正如Stephen在评论中指出的那样,如果使用multithreading同步上下文,则可以在多个OS线程中同时执行(以及所有复杂性和潜在的竞争条件)。 但MSDN引用是关于单线程上下文的情况。
最后,在其他地方使用相同的设计范例,您可以通过研究这些来学习很多关于async
/ await
的良好实践:
- Win32 Fibers (使用与线程相同的调用样式,但是合作)
- Win32 重叠I / O操作,Linux aio
- 协同程序
- 异步调用时,Azure KeyVault Active Directory AcquireTokenAsync超时
- 在C#Async CTP中`等待’线程会发生什么?
- DebuggerStepThrough,DebuggerHidden在async-await方法中不起作用
- Microsoft.Bcl.Async中是否存在ExceptionDispatchInfo的模拟?
- SmtpClient.SendMailAsync方法是否安全线程?
- 在Windows服务中执行任务循环的最佳方法
- entity framework异步记录计数与记录
- 使用Task.ContinueWith的异步回调
- 调试异步/等待(调用堆栈)中的exception