Según tengo entendido, Task.Yield al comienzo de un método obligará a la persona que llama a continuar si no está esperando el método. Mientras tanto Task.Run y ConfigureAwait(false) ejecutan una Tarea en un nuevo subproceso del grupo de subprocesos, lo que nuevamente obligará a la persona que llama a continuar si no está esperando el método.
No puedo entender la diferencia entre Task.Yield y ejecutar un nuevo subproceso de grupo de subprocesos, ya que justo después de que regresa a la persona que llama, continuará ejecutando el resto del método, que es esencialmente lo mismo.
Esta publicación sugiere que Yield y Task.Factory.StartNew (que en realidad es solo la versión anterior de Task.Run ) se pueden usar indistintamente, lo que me parece confuso.
Task.Yield no reemplaza a Task.Run y no tiene nada que ver con Task.ConfigureAwait .
Task.Yield : genera un awaitable que se completa justo después de que se verifique su finalización.ConfigureAwait(false) : genera una espera a partir de una tarea que ignora el SynchronizationContext capturado.Task.Run : ejecuta un delegado en un subproceso ThreadPool . Task.Yield es diferente de ConfigureAwait en que es un awaitable por sí mismo, y no un envoltorio configurable de otro awaitable (es decir, la Task ). Otra diferencia es que Task.Yield continúa en el contexto capturado.
Task.Run es diferente a ambos, ya que solo toma un delegado y lo ejecuta en ThreadPool , puede usarlo con ConfigureAwait(false) o sin él.
Task.Yield debe usarse para forzar un punto asíncrono, no como reemplazo de Task.Run . Cuando se alcanza await en un método asíncrono, comprueba si la tarea (u otra espera) ya se completó y, de ser así, continúa sincrónicamente. Task.Yield evita que eso suceda, por lo que es útil para realizar pruebas.
Otro uso es en los métodos de la interfaz de usuario, donde no desea acaparar el único subproceso de la interfaz de usuario, inserta un punto asíncrono y el resto está programado para ejecutarse en un momento posterior.
Task.Yield continúa en el contexto de sincronización actual o en el TaskScheduler actual, si hay uno presente. Task.Run no hace eso. Siempre utiliza el grupo de subprocesos.
Por ejemplo, Task.Yield permanecería en el subproceso de la interfaz de usuario.
Evite Task.Yield . Su semántica es menos clara. La respuesta vinculada es un olor a código.