I'm currently trying to call asynchronously an expensive method in blazor WASM while not blocking the UI thread.
According to answers to this question, it is impossible. However, these date back to a couple of years ago, and according to the WebAssembly roadmap, threading is supported by modern browsers.
Also, I can await
function calls without blocking the UI thread, as long as the functions are awaitable from the bottom up.
In the following code snippet, clicking the Foo
button will cause the UI to hang for a couple of seconds while the operation is carried out, but clicking the Bar
button will process a similar (but awaitable) operation in the background while keeping the UI responsive.
If WebAssembly doesn't support multi-threading, why does the second option seem to work with multiple threads? If it does support multi-threading, why does the first option block the UI?
@page "/asynctest"
<div class="row">
<div class="col">
@DisplayValue
</div>
<div class="col">
<button type="button" @onclick="OnClickFoo">Foo</button>
</div>
<div class="col">
<button type="button" @onclick="OnClickBar">Bar</button>
</div>
</div>
@code{
private string DisplayValue = "";
private double Result;
private async Task OnClickFoo(EventArgs e)
{
DisplayValue = "Working...";
Result = await Task.Run(() => Frobnicate()); // Blocks UI thread
DisplayValue = Result.ToString();
}
private async Task OnClickBar(EventArgs e)
{
DisplayValue = "Working...";
Result = await FrobnicateAsync(); // Doesn't block UI thread
DisplayValue = Result.ToString();
}
private int Frobnicate()
{
Thread.Sleep(2000); // do some heavy work
return 42;
}
private async Task<int> FrobnicateAsync()
{
await Task.Delay(2000); // do some heavy work async
return 42;
}
}