.net Blazor服务器按钮在等待时刷新

kiz8lqtg  于 2023-04-22  发布在  .NET
关注(0)|答案(1)|浏览(132)

我有一个按钮,就像下面的一个剃刀服务器组件页面。目的是当按钮被点击,按钮进入禁用模式,直到任务完成。这在一个页面上工作,但我不能设法让它在同一个应用程序的其他页面工作。按钮确实触发了DoSearch()函数,并在完成时刷新内容,但中途不更新自己。请问为什么?

<button type="button" class="btn btn-primary" @onclick="DoSearch" disabled="@SearchDisabled">@SearchBtnName</button>
protected bool SearchDisabled { get; set; } = false;
        protected string SearchBtnName { get; set; } = "Search";

        protected async Task DoSearch()
        {
            SearchDisabled = true;
            SearchBtnName = "Searching ...";
            List<string> log = new();

            try
            {
                //Do some work which takes a few seconds ....
            }
            finally
            {
                SearchDisabled = false;
                SearchBtnName = "Search";
            }

        }

我试着改变我编写onclick的方式,比如:@onclick="@(async()=〉await DoSearch())”
我尝试调用StateHasChanged()并等待InvokeAsync(StateHasChanged);我也试着看看那一页还有什么不同的地方,但没能弄清楚。

htrmnn0y

htrmnn0y1#

你的代码只有在如果*做一些工作 * 才能工作。如果它是 Package 在Task中的同步代码块,那么渲染器没有线程时间来更新UI,直到 * 做一些工作 * 完成,并且你已经将状态字段设置回完成。
我想引用今天一个类似问题的答案:
调用StateHasChanged不会渲染组件。它会将组件的RenderFragment在Renderer的队列中排队。该队列仅在Renderer获得线程运行时间时才得到服务[由Renderer和所渲染的组件]。
在下面的代码中,我引入了一个yield,一旦状态字段被更新,以确保UI在此时得到更新。

@page "/"

<PageTitle>Index</PageTitle>

<h1>Hello, world!</h1>

<div class="m-2 p-2">
    <button type="button" class="btn btn-primary" @onclick="DoSearch" disabled="@SearchDisabled">@this.SearchBtnName</button>
</div>

@code {
    protected bool SearchDisabled = false;
    protected string SearchBtnName = "Search";

    private async Task DoSearch()
    {
        SearchDisabled = true;
        SearchBtnName = "Searching ...";

        // make sure we yield to update the UI
        // Do work may be a block of synchronous wrapped in a Task!
        // Some people will suggest you do await Task.Delay(1) here Take your choice
        await Task.Yield();
        //await Task.Delay(1);

        await this.DoWork();

        SearchDisabled = false;
        SearchBtnName = "Search";
    }

    private async Task DoWork()
    {
        // emulate real async work
        await Task.Delay(2000);
    }
}

相关问题