从Blazor客户端中长期运行的后台任务中释放UI的推荐方法是什么

时间:2019-04-01 12:43:48

标签: azure blazor

我们的Blazor(客户端)应用由同时存在于UI上的许多组件组成。其中之一必须对Azure SQL进行大量的大数据调用。不管它是否具有UI焦点,此组件都将执行这些调用。这些调用中的每个调用最多可能需要3秒钟才能返回其结果,在此期间它将使UI失去响应。在不使用Blazor服务器端的情况下,如何在这些调用期间使UI保持响应。使用Task.Run等在单线程体系结构中无济于事。使用加载微调器也不是一种选择,因为这仍然会使UI无响应,并且可能对用户不可见。在当前的Blazor 0.9.0中有什么方法可以实现这一目标?

运行最新的Blazor预览版(0.9.0-preview3-19154-02)

4 个答案:

答案 0 :(得分:2)

您可以使用Invoke,我修改了counter示例页面进行了说明,您将需要一种单例DI对象,以避免将过程运行两次。

记住Blazor是一个实验性项目。另外,这个答案也是一种实验方法。

@page "/counter"

<h1>Counter</h1>

<p>Current count: @currentCount</p>

<button class="btn btn-primary" onclick="@IncrementCount">Click me</button>

@functions {
    int currentCount = 0;

    void IncrementCount()
    {
        currentCount++;
    }

    protected  override void OnInit()
    {
        Invoke(
            //here your task.
            async () =>
            {
                for(var i =0; i< 50; i++)
                {
                    await Task.Delay(1000);
                    currentCount++;
                    StateHasChanged();                    
                    System.Console.WriteLine("Still running ...");
                }
            });
    }
}

答案 1 :(得分:1)

如果异步调用没有帮助,那么您可以使用浏览器工作程序,只需实现一些js互操作即可。

答案 2 :(得分:0)

我在Task()。Start()上取得了成功

将您的工作放入异步任务,如下所示:

async Task MyWork()
{
    //sleep 10000
}

现在从任何您不希望此工作阻止呼叫的地方:

new Task( () => MyWork()).Start() );

我只在Blazor Server上使用过此功能,因此尚未在Client Blazor上进行过测试,因为它在单线程上运行,因此听说会有不同的结果。

答案 3 :(得分:-1)

建议的答案不起作用,对我来说,我最终使用了:

 protected override void OnInitialized()
 {
    InvokeAsync(async () =>
    {
        myvar = await YourCodeHere();
        StateHasChanged();

    });
    base.OnInitialized();
}

public async Task<MyVarType> YourCodeHere()
{
    ...
} 

说明:我有一个名为 MyVarType 的类,我用它来显示 Razor 组件上的值。我有一个用该类实例化的 myVar 变量,最初它是空的。该组件将立即呈现其默认值。初始化后,变量也从 OnInitialized 方法异步分配。 YourCodeHere 函数可能需要几秒钟的时间。 Razor 组件在调用 StateHasChanged() 时会重新渲染,以便显示加载的值。