在 Blazor 服务器端应用程序中,我有无限的 while 循环来使用 razor.cs 页面中 Kafka 主题的数据。如何防止它阻塞 UI?

问题描述 投票:0回答:1

在我的 razor.cs 文件中,我有以下异步任务,该任务在无限的 while 循环中消耗来自 Kafka 主题的数据。当消费开始时,用户界面被阻止,用户无法离开页面或执行其他操作。我怎样才能防止这种情况发生?我想保留 while 循环。 通常,当用户离开页面时,我想关闭与 Dispose 的连接

我的razor.cs代码:

protected override void OnInitialized()
{
  Read_Status_from_Kafka();
}


public async Task Read_Status_from_Kafka()
{
  // code for configuring Kafka connection
  while (true)
  {
     //consuming data form Kafka topic
  }
}
c# while-loop blazor-server-side
1个回答
0
投票

正如您所发现的,线程[在本例中为同步上下文]一次只能做一件事。您期望的是您可以将其放入监视器循环中并同时响应 UI 事件。

如果您想一直读取数据,那么后台任务是一个很好的解决方案。

如果您只想在页面处于活动状态时读取数据,您可以使用计时器来执行此操作。这将 while 循环的操作“卸载”到计时器,该计时器已经在专用线程上运行这样的循环来处理所有注册的计时器。

这是一个演示页面,它在页面上设置一个计时器每秒运行一次,并在发生变化时更新 UI。

@page "/"
@implements IDisposable

<PageTitle>Home</PageTitle>

<h1>Hello, world!</h1>

Welcome to your new app.

<div class="bg-dark text-white p-2 m-2">
    <pre>@_message</pre>
</div>

@code{
    private Timer? _timer;
    private string? _message;
    private volatile bool _isProcessing;  //mark as volatile for thread safely

    protected override void OnInitialized()
    {
        // Kick off the timer on the Timer Service
        _timer = new Timer(this.OnTimerExpired, null, 1000, 1000);
    }

    // Note that this method will be executed on a threadpool thread by the Timer service
    // not on the UI thread [synchronisation context]
    // isProcesssing ensures we only run one OnTimerExpired at once
    private async void OnTimerExpired(object? state)
    {
        if (_isProcessing)
            return;

        _isProcessing = true;
        //fake Read_Status_from_Kafka();
        await Task.Delay(500);

        // Update the UI if something has changed
        if(true)
        {
            _message = $"Updated at {DateTime.Now.ToLongTimeString()}";
            // invoke the UI update on the UI thread [synchronisation context]
            await this.InvokeAsync(StateHasChanged);
        }
        _isProcessing = false;
    }

    public void Dispose()
    {
        _timer?.Dispose();
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.