Ako funguje Task.Yield
práce pod kapotou v Mono/WASM runtime (ktorý používa Blazor WebAssembly)?
Na objasnenie, verím, že majú dobré znalosti o tom, ako Task.Yield
pracuje v .NET Framework a .NET Core. Mono vykonávanie nevyzerá veľmi odlišná, v skratke, príde na to:
static Task Yield()
{
var tcs = new TaskCompletionSource<bool>();
System.Threading.ThreadPool.QueueUserWorkItem(_ => tcs.TrySetResult(true));
return tcs.Task;
}
Prekvapivo to funguje v Blazor WebAssembly, príliš (skúste si to online):
<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();
}
}
}
Prirodzene, to všetko sa deje na tú istú udalosť slučky niť v prehliadači, takže som zvedavý, ako to funguje na nižšej úrovni.
Mám podozrenie, že by mohlo byť využitie niečo ako Emscripten je Asyncify, ale nakoniec sa to použiť nejakú Webovú Platformu API naplánovať pokračovanie spätný hovor? A ak áno, ktoré presne jeden (ako queueMicrotask
, setTimout
, Promise.resove().then
atď.)?
Aktualizovaná, práve som zistil, že Thread.Sleep
je implementovaný ako dobre a je to vlastne blokuje prípade slučky niť
setTimeout
, mohli by ste vysvetliť, obrovský rozpor som videl, keď načasovanie a slučkaawait new Promise(r => setTimeout(r, 0))
s JS interop vs slučkaawait Task.Yield
? Je tam chyba v teste? blazorrepl.telerik.com/QlFFQLPF08dkYRbm30