Task.Yield,Task.Run和ConfigureAwait(false)之间有什么区别?

Jam*_* Ko 9 c# multithreading asynchronous task async-await

据我所知,Task.Yield在方法开始时,如果没有等待方法,将强制调用者继续.同时Task.Run,ConfigureAwait(false) 两者都在一个新线程池线程上运行一个Task,如果它没有等待该方法,它将再次强制调用者继续.

我无法理解Task.Yield和运行新线程池线程之间的区别,因为在它返回调用者之后,它将继续执行该方法的其余部分,这基本上是相同的.

后表明,YieldTask.Factory.StartNew(这实际上只是老版本的Task.Run)可以互换使用,这似乎令人困惑我.

i3a*_*non 8

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`无法避免UI限制,因为UI消息队列具有优先级(并且continuation始终优先于`WM_PAINT`). (3认同)
  • @v.oddou:后续问题应该是他们自己的问题(SO 是问答网站,而不是论坛)。简短回答:`await` 会将方法继续发布到当前的 `SynchronizationContext` 实例,该实例在幕后使用 `BeginInvoke`(或等效的)。 (2认同)

usr*_*usr 5

Task.Yield继续当前的同步上下文或当前的同步上下文TaskScheduler.Task.Run不这样做.它总是使用线程池.

例如,Task.Yield将保留在UI线程上.

避免Task.Yield.它的语义不太清楚.链接的答案是代码气味.