C# .NET 5.0 Wpf UI 被另一个线程修改

C# .NET 5.0 Wpf UI modified by another thread

我在从另一个线程更新 WPF UI 时遇到了一些问题。 第二个线程是一个不断从 StreamReader 读取消息的循环。 在这些消息中,有更新 UI.

的命令

我不知道该怎么做。我阅读了有关类似问题的文章,但并不相同

WPF 接口:

private void Button_Click(object sender, RoutedEventArgs e)
{
   Thread threadConsume = new Thread(pre_sub);
   threadConsume.Start();
}

其他线程:

private void pre_sub()
{
    Subscribe();
}
public async Task Subscribe()
{
  while (true)
  {
    try
    {
       Console.WriteLine("Establishing connection");
       using (var streamReader = new StreamReader(await _client.GetStreamAsync(_urlSubscription)))
       {
          while (!streamReader.EndOfStream)
          {
              var stream = await streamReader.ReadLineAsync();
              if (stream.ToString() == "update")
              {
                  //update the WPF UI
              }
          }
       }
    }
    catch (Exception ex)
    {
    }
  }
}

不要在已经进行异步调用时创建线程。

只需在异步事件处理程序中调用并等待异步方法即可。因此 UI 更新将在 UI 线程中进行。不需要 Dispatcher 调用。

private async void Button_Click(object sender, RoutedEventArgs e)
{
    await Subscribe();
}

除此之外,您显然需要某种机制来停止 Subscribe 方法中的无限循环。

您需要使用BeginInvoke 方法。符合以下内容:

  .....
    while (!streamReader.EndOfStream)
          {
                  var stream = await streamReader.ReadLineAsync();
                  if (stream.ToString() == "update")
                  {                          
                   var dispatcher = Application.Current.MainWindow.Dispatcher;
                   dispatcher.BeginInvoke(new Action(() =>
                   {
                     //update the WPF UI
                   }), (DispatcherPriority)10);
                  }
          }
   break; ///if UI Updated exit the while true loop            
.....

另外,作为旁注,不要每次都吞下异常。日志 or/and 处理 catch 块上的异常

您必须调用调度程序才能更新 UI

Dispatcher.BeginInvoke(() =>
         {
             //Update the UI
         });