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

Blazor结合SignalR无法更新UI组件问题求助

问题分析与解决

你的代码中,虽然能收到SignalR消息、调用了BroadcastData和StateHasChanged,但页面列表不更新的核心问题在于**async void方法的使用**。SignalR的回调运行在后台线程,async void会导致异步操作的上下文管理异常,进而让StateHasChanged无法正确触发UI渲染。

修复方案一:直接在SignalR回调中处理更新

修改OnInitializedAsync中的Hub注册逻辑,使用异步委托直接处理:

protected override async Task OnInitializedAsync()
{
    devices = await deviceRepository.GetDeviceList();

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

    // 直接在回调中异步处理UI更新
    hubConnection.On<List<DTO.Device>>("RefreshDevice", async (payload) =>
    {
        await InvokeAsync(() =>
        {
            devices = payload;
            StateHasChanged();
        });
    });

    await hubConnection.StartAsync();
    
    await base.OnInitializedAsync(); // 补全await,确保基类初始化完成
}

修复方案二:将BroadcastData改为async Task

如果需要保留单独的方法,避免使用async void,改为返回async Task并在回调中await:

protected override async Task OnInitializedAsync()
{
    devices = await deviceRepository.GetDeviceList();

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

    hubConnection.On<List<DTO.Device>>("RefreshDevice", async (payload) =>
    {
        await BroadcastData(payload); // await异步方法,确保上下文正确
    });

    await hubConnection.StartAsync();
    
    await base.OnInitializedAsync();
}

// 替换async void为async Task
private async Task BroadcastData(List<DTO.Device> payload)
{
    await InvokeAsync(() =>
    {
        devices = payload;
        this.StateHasChanged();
    });
}

额外注意点

  • 原代码中base.OnInitialized();未加await,会导致基类初始化逻辑可能未完成就执行后续代码,必须补全await。
  • 确认DTO.Device的属性均为public且包含getter(你初始化时能正常显示,这一点应该已满足)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 18:07:29