Blazor-Wasm:为什么 `await Task` 会阻塞 UI,但 `await`-`async` 不会?

gaz*_*zoh 1 c# async-await blazor blazor-webassembly

我目前正在尝试在 blazor WASM 中异步调用一个昂贵的方法,同时不阻塞 UI 线程。

根据这个问题的回答,这是不可能的。然而,这些可以追溯到几年前,根据WebAssembly 路线图,现代浏览器支持线程。

另外,我可以await在不阻塞 UI 线程的情况下调用函数,只要函数是自下而上等待的。

在下面的代码片段中,单击按钮Foo将导致 UI 在执行操作时挂起几秒钟,但单击按钮Bar将在后台处理类似(但可等待)的操作,同时保持 UI 响应。

如果 WebAssembly 不支持多线程,为什么第二个选项似乎适用于多线程?如果它确实支持多线程,为什么第一个选项会阻塞 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

小智 6

据我所知,Blazor WASM 不支持多线程,您只能获得 1 个线程。

在“OnClickBar”方法中,您没有创建不同的线程。您正在使用 async/await 状态机,它将控制权返回给调用线程。不会Task.Delay(2000)阻塞线程,如Stack Overflow 问题中所示

在“OnClickFoo”方法中,您正在调用 Task.Run,​​它会尝试创建一个后台线程 - 这在 WASM 中无法正常工作,因为您只有一个线程,因此当您调用时Thread.Sleep(2000);- UI 线程正在休眠。

有关线程的更多信息,请参见此处:Microsoft Docs - Threads

相关堆栈溢出问题

  • 这是对的。多线程 WASM 已经在路线图上,但是什么时候......???。`Thread.Sleep` 正在阻塞并阻塞唯一可用的线程。 (3认同)
  • 确切地说,线程应该在 .net 7 中引入,但尚未在当前预览版中 https://devblogs.microsoft.com/dotnet/asp-net-core-updates-in-dotnet-7-preview- 2/. 另请参阅此线程 https://github.com/dotnet/aspnetcore/issues/17730 (3认同)