我试图了解Async
编程和Multi Threaded
编程之间的区别。在async
中,我们说线程接受一个task(T1)并开始执行它。如果同时有另一个任务(T2)出现,它不会等待T1完成,而是在T1在后台执行时选择第二个任务T2。
突出显示的部分是我最困惑的部分 周围。那么,当线程接收到T2时,谁在执行T1?是什么 线程在操作系统上下文中的作用?它到底是做什么的?
这可能是一个愚蠢的问题,但是我在互联网上经历了数小时的磨难却没有得到满意的结果。还是我只是问错了一个问题?
答案 0 :(得分:2)
实际上,这种困惑来自任务T1在后台执行的想法。仅当T1是一个IO绑定任务,因此它不占用线程(因此它不执行,而是在等待某些IO设备驱动程序的结果)时,才可能出现您所描述的场景。 IO操作正在运行。在这种情况下,线程并不繁忙,可以进行其他工作。
如果您有一个纯粹的CPU绑定任务,则始终需要一个线程来运行。如果要将此操作卸载到 ThreadPool 线程(例如,为了通过从主UI线程上卸载工作来使UI保持响应),则常见的模式是使用 Task.Run。 :
await Task.Run(/* your CPU-bound method call here */);
当涉及到异步/等待,任务,TPL等时,我发现Stephen Cleary的解释非常有用。因此,这里是您可能需要关注的链接,以进行更详细的解释:
我认为,当您进一步深入一层时,它总是会奏效的,在 async / await 的情况下,这将是经典的线程。有一个很棒的(免费的)Threading in C# by Joseph Albahari。在这里,您将找到有关线程,同步,并行编程的所有重要细节。
答案 1 :(得分:2)
如果通过async
编程,则意味着异步编程仅意味着在某些事件可能以未严格定义的顺序(周期)发生时,对计算流程进行编程。从这个角度来看,两种机制:线程和I / O是异步的。但是,.NET async
机制与它们没有直接关系。从本质上讲,这只是一个框架,用于将类似于异步的计算包装为某种形式,该形式将模仿同步执行但保留异步语义。也就是说,它不能控制基础操作是异步操作还是同步操作(由操作本身控制),甚至可以成功地将其应用于两种类型的操作,但将其与异步操作一起使用会更有益,这很可能为什么开发人员将这种机制与异步编程紧密地联系在一起。因此,您的问题的答案是“取决于情况”。对于受I / O约束的异步操作,它的IO子系统以及I / O设备可以在拾取并执行T2时提供T1的执行。对于CPU绑定的异步操作,它可以是另一个线程。如果操作是同步的,它们将被同步地一个接一个地执行。