Jam*_* Ko 9 c# multithreading asynchronous task async-await
据我所知,Task.Yield
在方法开始时,如果没有等待方法,将强制调用者继续.同时Task.Run
,ConfigureAwait(false)
两者都在一个新线程池线程上运行一个Task,如果它没有等待该方法,它将再次强制调用者继续.
我无法理解Task.Yield
和运行新线程池线程之间的区别,因为在它返回调用者之后,它将继续执行该方法的其余部分,这基本上是相同的.
这后表明,Yield
和Task.Factory.StartNew
(这实际上只是老版本的Task.Run
)可以互换使用,这似乎令人困惑我.
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
继续当前的同步上下文或当前的同步上下文TaskScheduler
.Task.Run
不这样做.它总是使用线程池.
例如,Task.Yield
将保留在UI线程上.
避免Task.Yield
.它的语义不太清楚.链接的答案是代码气味.