Nasıl yapar Task.Yield
Mono / WASM çalışma zamanında kaputun altında çalışın (Blazor WebAssembly tarafından kullanılır)?
Netleştirmek için, ben inanıyorum ki iyi bir anlayış nasıl Task.Yield
çalışmalar içinde .NET Çerçeve ve .NET Çekirdek. Mono uygulama çok farklı görünmüyor, özetle, buna geliyor:
static Task Yield()
{
var tcs = new TaskCompletionSource<bool>();
System.Threading.ThreadPool.QueueUserWorkItem(_ => tcs.TrySetResult(true));
return tcs.Task;
}
Şaşırtıcı bir şekilde, bu Blazor Webassembly'da da çalışır (çevrimiçi deneyin).:
<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();
}
}
}
Doğal olarak, hepsi tarayıcıda aynı olay döngüsü iş parçacığında gerçekleşir, bu yüzden alt düzeyde nasıl çalıştığını merak ediyorum.
Emscripten'in Asyncify gibi bir şey kullanıyor olabileceğinden şüpheleniyorum, ancak sonunda devam eden bir geri arama planlamak için bir çeşit Web Platformu API'sı kullanıyor mu? Ve eğer öyleyse, tam olarak hangisi (örneğinqueueMicrotask
, setTimout
, Promise.resove().then
, vb.)?
Güncellendi, bunu yeni keşfettim Thread.Sleep
bu da uygulanır ve aslında olay döngüsü iş parçacığını engeller
setTimeout
, bir döngüyü zamanlarken gördüğüm büyük bir tutarsızlığı açıklayabilir misinizawait new Promise(r => setTimeout(r, 0))
JS ınterop vs bir döngü ileawait Task.Yield
? Testte bir kusur mu var? blazorrepl.telerik.com/QlFFQLPF08dkYRbm30