【发布时间】:2022-03-01 19:21:07
【问题描述】:
我正在尝试在 Blazor 中创建一个异步方法,该方法允许我异步运行计算量大的代码,然后在完成后更新组件,同时保持页面响应。这个问题与其他关于 Blazor 中异步的问题之间的区别在于,我正在创建一个需要很长时间的方法,而不是使用诸如 HttpClient 的下载方法之类的方法。
组件:
page.blazor
@inject ClassA classA
<button class="btn btn-primary" @onclick="@doWork">Do Work</button>
<Text>@log</Text>
@code {
async Task doWork()
{
log = await classA.doWork();
}
}
C# 类
public class ClassA
{
public async Task<string> doWork()
{
ClassB classB = new ClassB();
var result = await classB.Execute();
return result;
}
}
public class ClassB
{
// This method is meant to take a long time and execute asynchronously
public async Task<string> Execute()
{
string k = "";
for (int i = 0; i < 10000000; i ++)
{
k = i.ToString();
}
return k;
}
}
注意:如果我将 page.blazor 中的代码更改为
@code {
async Task doWork()
{
await Task.Delay(10000);
log = "Done";
}
}
它工作正常。
【问题讨论】:
-
Task.Run 是你所需要的
-
在 Blazor WebAssembly 中,这暂时不起作用。对于 CPU 工作,您需要额外的线程,而这里没有它们。 Task.Run() 没有多大帮助,您需要一台服务器和/或将工作切成小块。
-
Task.Delay()是异步的,用它来模拟 I/O。Thread.Sleep()是同步的,你可以用它来模拟 CPU 负载。 -
您能否确认这是一个 Blazor WASM 应用程序?标签之一是“Blazor-webassembly”,但请务必确定,因为它很重要!
-
多线程是 .Net 7 Wasm 路线图的一部分。(github.com/dotnet/aspnetcore/issues/…)。虽然它不在第一次预览中。不幸的是,除了在下面的答案中尝试产量(或 Task.Delay(非常短的毫秒跨度)或其他东西)以便您为其余的执行留出时间)之外,除了尝试优化您之外没有什么可做的尽可能多地编码。至少现在
标签: c# .net asynchronous blazor blazor-webassembly