Task.Yield、Task.Run 和 ConfigureAwait(false) 之间有什么区别?
What's the difference between Task.Yield, Task.Run, and ConfigureAwait(false)?
据我了解,方法开头的 Task.Yield
将强制调用者继续(如果它不在等待该方法)。同时 Task.Run
和 ConfigureAwait(false)
both 运行 新线程池线程上的任务,如果调用者不在等待该方法,这将再次强制调用者继续。
我无法理解 Task.Yield
和 运行 新线程池线程之间的区别,因为在它 returns 到调用者之后,它会继续执行其余的的方法,本质上是一样的。
This post 表明 Yield
和 Task.Factory.StartNew
(实际上只是 Task.Run
的旧版本)可以互换使用,这似乎让我感到困惑。
Task.Yield
在当前同步上下文或当前 TaskScheduler
上继续(如果存在的话)。 Task.Run
不会那样做。它总是使用线程池。
例如 Task.Yield
将留在 UI 线程上。
避免Task.Yield
。它的语义不太清楚。链接的答案是代码味道。
Task.Yield
不是 Task.Run
的替代品,它与 Task.ConfigureAwait
.
无关
Task.Yield
- 生成一个在检查完成后立即完成的可等待对象。
ConfigureAwait(false)
- 从忽略捕获的 SynchronizationContext
. 的任务生成可等待对象
Task.Run
- 在 ThreadPool
线程上执行委托。
Task.Yield
与 ConfigureAwait
的不同之处在于它本身就是一个可等待对象,而不是另一个可等待对象(即 Task
)的可配置包装器。另一个区别是 Task.Yield
确实在捕获的上下文中继续。
Task.Run
与两者不同,因为它只需要一个委托并在 ThreadPool
上运行它,您可以在 ConfigureAwait(false)
或不使用它的情况下使用它。
Task.Yield
应该用于强制异步点,而不是替代 Task.Run
。当在异步方法中到达 await 时,它会检查任务(或其他可等待的任务)是否已经完成,如果已完成,它会继续同步。 Task.Yield
防止这种情况发生,因此对测试很有用。
另一种用法是在 UI 方法中,您不想占用单个 UI 线程,您插入一个异步点,其余部分安排在稍后执行时间。
据我了解,方法开头的 Task.Yield
将强制调用者继续(如果它不在等待该方法)。同时 Task.Run
和 ConfigureAwait(false)
both 运行 新线程池线程上的任务,如果调用者不在等待该方法,这将再次强制调用者继续。
我无法理解 Task.Yield
和 运行 新线程池线程之间的区别,因为在它 returns 到调用者之后,它会继续执行其余的的方法,本质上是一样的。
This post 表明 Yield
和 Task.Factory.StartNew
(实际上只是 Task.Run
的旧版本)可以互换使用,这似乎让我感到困惑。
Task.Yield
在当前同步上下文或当前 TaskScheduler
上继续(如果存在的话)。 Task.Run
不会那样做。它总是使用线程池。
例如 Task.Yield
将留在 UI 线程上。
避免Task.Yield
。它的语义不太清楚。链接的答案是代码味道。
Task.Yield
不是 Task.Run
的替代品,它与 Task.ConfigureAwait
.
Task.Yield
- 生成一个在检查完成后立即完成的可等待对象。ConfigureAwait(false)
- 从忽略捕获的SynchronizationContext
. 的任务生成可等待对象
Task.Run
- 在ThreadPool
线程上执行委托。
Task.Yield
与 ConfigureAwait
的不同之处在于它本身就是一个可等待对象,而不是另一个可等待对象(即 Task
)的可配置包装器。另一个区别是 Task.Yield
确实在捕获的上下文中继续。
Task.Run
与两者不同,因为它只需要一个委托并在 ThreadPool
上运行它,您可以在 ConfigureAwait(false)
或不使用它的情况下使用它。
Task.Yield
应该用于强制异步点,而不是替代 Task.Run
。当在异步方法中到达 await 时,它会检查任务(或其他可等待的任务)是否已经完成,如果已完成,它会继续同步。 Task.Yield
防止这种情况发生,因此对测试很有用。
另一种用法是在 UI 方法中,您不想占用单个 UI 线程,您插入一个异步点,其余部分安排在稍后执行时间。