如何 Task.Yield
工作罩下在 单/WASM运行时 (这是由Blazor WebAssembly)?
为了澄清,我相信我有一个很好的理解 如何 Task.Yield
工作 中。净框架。净的核心。 单实施 看起来并不太大的不同,概括地说,它涉及到这个:
static Task Yield()
{
var tcs = new TaskCompletionSource<bool>();
System.Threading.ThreadPool.QueueUserWorkItem(_ => tcs.TrySetResult(true));
return tcs.Task;
}
令人惊讶的是,这一工作在Blazor WebAssembly,太(尝试在线):
<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();
}
}
}
当然,这一切都发生在同一事件循环线浏览器,所以我不知道它是如何工作在较低的水平。
我怀疑,它可能是利用喜欢的东西 Emscripten的Asyncify,但最终,它是否使用某种形式的网络平台API要安排延续回? 如果是,哪一个正(喜欢 queueMicrotask
, setTimout
, Promise.resove().then
等)?
更新,我刚发现 Thread.Sleep
实现,以及它实际上 块的事件循环线
setTimeout
你能解释一个巨大的差异,我看到了当时的一个循环await new Promise(r => setTimeout(r, 0))
与JS互操作vs的一个循环await Task.Yield
? 是有缺陷的测试? blazorrepl.telerik.com/QlFFQLPF08dkYRbm30