You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Blazor Server中InvokeAsync(StateHasChanged)无法更新表格UI求助

问题解决:Blazor SignalR回调中UI不更新的问题

核心原因

SignalR的回调运行在后台线程,虽然你调用了InvokeAsync(StateHasChanged),但同步回调中未等待异步操作完成,导致组件变更检测未被正确触发;直接调用StateHasChanged则会因为不在Dispatcher线程而抛出异常。

解决方案

将SignalR的回调改为异步方法,并等待InvokeAsync(StateHasChanged)执行完成,确保UI线程正确处理组件状态更新。同时添加连接断开重连逻辑,提升稳定性。

修改后的完整代码

@page "/online-chat"

@foreach (var post in PostsList)
{
    <p>@post.AuthorName | @post.MessageText</p>
}

@using Microsoft.AspNetCore.SignalR.Client;
@using StudujFriUniza.Data;
@using StudujFriUniza.Services;
@inject PostsService postsService;
@inject NavigationManager Navigation

@code {
    List<Post> PostsList = new List<Post>();
    private HubConnection? hubConnection;

    protected override async Task OnInitializedAsync()
    {
        PostsList = await postsService.GetAllPosts();

        hubConnection = new HubConnectionBuilder()
            .WithUrl(Navigation.ToAbsoluteUri("/postsHub"))
            .Build();

        // 改为异步回调并等待InvokeAsync完成
        hubConnection.On<List<Post>>("RefreshPosts", async posts =>
            {
                PostsList = posts;
                await InvokeAsync(StateHasChanged);
            });

        // 添加连接断开自动重连逻辑
        hubConnection.Closed += async (error) =>
        {
            await Task.Delay(new Random().Next(0, 5) * 1000);
            await hubConnection.StartAsync();
        };

        await hubConnection.StartAsync();
    }

    // 组件销毁时关闭连接
    public async ValueTask DisposeAsync()
    {
        if (hubConnection != null)
        {
            await hubConnection.DisposeAsync();
        }
    }
}

关键修改点

  • 将hubConnection.On的回调改为async方法,并用await等待InvokeAsync(StateHasChanged),确保UI线程完成状态变更检测。
  • 添加Closed事件处理,当SignalR连接断开时自动尝试重连,避免后续消息无法接收。
  • 实现DisposeAsync接口,在组件销毁时关闭HubConnection,释放资源。

内容的提问来源于stack exchange,提问作者absolutty

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 05:23:33