【问题标题】:Does 'await Task.Delay(1000)' block ANY thread?'await Task.Delay(1000)' 会阻塞任何线程吗?
【发布时间】:2015-11-08 12:21:13
【问题描述】:

我读过建议等待 Task.Delay() 不要阻塞调用线程(与 Task.Delay().Wait() 和 Thread.Sleep() 相反)。但随着我对 async/await 的了解越来越多,我感觉它所做的只是将可等待的任务转移到另一个线程上执行。

那么,我是否理解正确:await Task.Delay() 不会阻塞调用线程,但它会阻塞 SOME 线程,等待的任务转移到哪里?

如果该陈述为真,那么您能否建议我使用一种要求任务等待一段时间而不在​​等待期间阻塞任何线程的方法?

【问题讨论】:

标签: c# .net multithreading asynchronous


【解决方案1】:

但是它阻塞了一些线程,等待的任务转移到哪里?

这取决于您所说的“阻止”。它不会导致任何线程进入睡眠状态 1 秒,或者(更糟)旋转等待延迟完成。相反,它有效地安排一个计时器在 1 秒内触发,然后执行由于 await 而注册的延续。

在某种简化的层面上,await 只是转换为:

  • 在 awaitable 上调用 GetAwaiter,以获取 awaiter
  • 检查 awaiter 是否已经完成 - 如果是,则继续
  • 否则,与等待者安排继续,然后返回
  • 当 awaiter 完成时,将调用 continuation 并继续 async 方法

聪明的一点是编译器保存状态和管理延续的方式,以便它从await 表达式的末尾继续。

【讨论】:

  • 所以据我所知,等待的Delay() 任务被发送到的线程可用于处理其他任务,而Delay() 正在进行中?
  • @cubrman:“等待的 Delay() 任务被发送到哪里”是什么意思? Delay() 返回一个Task,并且该任务在一秒钟后完成......这并不是一个实际上任何事情的任务。如果您对 System.Timers.Timer 的工作方式(或类似方式)感到满意,那就是这样。
  • @cubrman 进程不会发生“延迟”。它发生在称为时钟/计时器的硬件上。它无论如何都不会从 CPU 的程序逻辑部分占用资源。
  • @cubrman 你的问题就像在问“当我把闹钟定在早上时,我大脑的哪个部分负责检查什么时候起床的“任务”?”
【解决方案2】:

所以据我所知,等待的Delay() 任务被发送到的线程> 可用于处理其他任务,而Delay() 正在进行中? – cubrman 8 月 >15 日 10:19

不,您在等待 task.delay 时不能做其他事情。下面的指令不会被执行,但线程也不会被阻塞!这意味着界面处理仍然可以工作,例如您可以移动鼠标、单击按钮等。

【讨论】:

  • 但是你可以启动Task,做一些事情,然后await
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-18
相关资源
最近更新 更多