¿Cómo Task.Yield
el trabajo bajo el capó en Mono/WASM tiempo de ejecución (que es utilizado por Blazor WebAssembly)?
Para aclarar, yo creo que tengo una buena comprensión de cómo Task.Yield
obras en .NET Framework y .NET Core. Mono aplicación no es muy distinto, en pocas palabras, se trata de lo siguiente:
static Task Yield()
{
var tcs = new TaskCompletionSource<bool>();
System.Threading.ThreadPool.QueueUserWorkItem(_ => tcs.TrySetResult(true));
return tcs.Task;
}
Sorprendentemente, esto funciona en Blazor WebAssembly, demasiado (intentarlo en línea):
<label>Tick Count: @tickCount</label><br>
@code
{
int tickCount = System.Environment.TickCount;
protected override void OnAfterRender(bool firstRender)
{
if (firstRender) CountAsync();
}
static Task Yield()
{
var tcs = new TaskCompletionSource<bool>();
System.Threading.ThreadPool.QueueUserWorkItem(_ => tcs.TrySetResult(true));
return tcs.Task;
}
async void CountAsync()
{
for (var i = 0; i < 10000; i++)
{
await Yield();
tickCount = System.Environment.TickCount;
StateHasChanged();
}
}
}
Naturalmente, todo sucede en el mismo bucle de eventos hilo en el navegador, así que me pregunto cómo funciona en el nivel inferior.
Sospecho que podría ser la utilización de algo como Emscripten del Asyncify, pero con el tiempo, el uso de algún tipo de Plataforma Web API para programar una continuación de devolución de llamada? Y si es así, que uno exactamente (como queueMicrotask
, setTimout
, Promise.resove().then
, etc)?
Actualizado, he descubierto que Thread.Sleep
se implementa así y que en realidad se bloquea el bucle de eventos hilo
setTimeout
podría usted explicar una gran discrepancia estoy viendo cuando el tiempo de un bucle deawait new Promise(r => setTimeout(r, 0))
con JS interoperabilidad vs un bucle deawait Task.Yield
? Hay un error en la prueba? blazorrepl.telerik.com/QlFFQLPF08dkYRbm30