StateHasChanged 未在 Blazor 服务器应用程序上更新

Hap*_*ent 5 razor signalr blazor blazor-server-side blazor-webassembly

我正在通过 SignalR 连接与 ASP.NET Core API 开发 Blazor 服务器应用程序,此代码在 WebAssembly 中运行良好,但由于某种原因,它在 Blazor 服务器应用程序中不起作用。

我怀疑问题是StateHasChanged()没有生效,因为 Console.WriteLine($"Company Name: {item.CompanyName}, Volumn: {item.Volume}");在控制台中打印但MarketData没有更新 UI StateHasChanged()

了解更多背景信息;完整代码解释如下:

https://www.webnethelper.com/2022/01/aspnet-core-6-signalr-creating-real.html

但我想这只是一个常见的解决办法;但我找不到解决方案。

我也尝试过InvokeAsync(() => StateHasChanged());stackoverflow 中提到的方法,但没有成功。谁能帮我解决这个问题吗?

private HubConnection? hubConn;
private string? ConnectionStatusMessage;
public List<Market> MarketData = new List<Market>(); 
public List<Market> MarketReceivedData = new List<Market>(); 


private  List<string> xSource;
private  List<int> ySource;
private List<object> source; 

protected override async Task OnInitializedAsync()
{

    xSource = new List<string>();
    ySource = new List<int>();
    source = new List<object>();  

    await service.GetMarketEndpoint();
    await Start();
     
}


private async Task Start()
{
    hubConn = new HubConnectionBuilder().WithUrl("https://localhost:7193/marketdata").Build();
    await hubConn.StartAsync();
    if(hubConn.State == HubConnectionState.Connected )
        ConnectionStatusMessage = "Connection is established Successfully...";
    else
        ConnectionStatusMessage = "Connection is not established...";
}

private void MarketDataListener(string chartType)
{
    hubConn.On<List<Market>>("SendMarketStatusData", async (data) =>
    {
        MarketData = new List<Market>(); 
        foreach (var item in data)
        {
            Console.WriteLine($"Company Name: {item.CompanyName}, Volumn: {item.Volume}");
            xSource.Add(item.CompanyName);
            ySource.Add(item.Volume);
        }


        source.Add(ySource);
        source.Add(xSource);


        MarketData = data;

        StateHasChanged();

        await js.InvokeAsync<object>(chartType, source.ToArray());
        xSource.Clear();
        ySource.Clear();
    });
}

private void ReceivedMarketDataListener()
{
    hubConn.On<List<Market>>("CommunicateMarketData", (data) =>
    {
        MarketReceivedData = data;
        StateHasChanged();           
    });
}



public async Task Dispose()
{
    await hubConn.DisposeAsync();
}


async Task  generateLineChartTask()
{
    MarketDataListener("marketLineChart");
     ReceivedMarketDataListener();
    await service.GetMarketDataAsync();
}
 async Task   generateBarChartTask()
{
  MarketDataListener("marketBarChart"); 
   ReceivedMarketDataListener();
    await service.GetMarketDataAsync();
}
Run Code Online (Sandbox Code Playgroud)

Hen*_*man 3

这里的主要区别是 Blazor 服务器端是多线程的,因此电路中的回调将在不同的线程上执行。

StateHasChanged()必须在主 (UI) 线程上执行,因此将其称为 InvokeAsync(StateHasChanged),它是 的缩写InvokeAsync(() => StateHasChanged())

并注意其他线程风险。即,不要在线程之间共享诸如列表之类的数据。