c# - 为什么 Dispatcher.Invoke 不触发 UI 更新?

标签 c# wpf dispatcher

我正在尝试重用 UserControl 并借用一些跟踪进度的逻辑。我会尝试简化事情。 MyWindow.xaml 包含一个 MyUserControl。 MyUserControl 有自己的进度指示器(正在格式化...、正在复制文件...等),我想在 MyWindow 窗体的某处反射(reflect)此进度。但是,用户控件有一些我不太明白的逻辑。我读了又读,但我仍然不理解 Dispatcher。以下是用户控件中更新进度的逻辑摘要。

this.Dispatcher.Invoke(DispatcherPriority.Input, (Action)(() =>
{
   DAProgressIndicator = InfiniteProgress.AddNewInstanceToControl(StatusGrid, new SolidColorBrush(new Color() { A = 170, R = 128, G = 128, B = 128 }), string.Empty);
                DAProgressIndicator.Message = MediaCardAdminRes.ActivatingCard;
                ActivateInProgress = true;
}));

我想我会很聪明,向 MyUserControl 添加一个事件,该事件将在 ActivateInProgress 属性设置逻辑中调用。

   public bool ActivateInProgress 
   {
      get
      {
         return _activateInProgress;
      }
      set
      {
         _activateInProgress = value;
         if (ActivateInProgressHandler != null)
         {
            ActivateInProgressHandler(value);
         }
      }
   }

我将 MyWindow 构造函数中的 ActivateInProgressHandler 设置为以下方法,该方法设置用于窗口自身进度指示器的 View 模型属性。

private void SetActivation(bool activateInProgress)
{
   viewModel.ActivationInProgress = activateInProgress;
}

但是,窗口的进度指示器永远不会改变。所以,我确信 Dispatcher.Invoke 正在做一些我不明白的事情。如果我在 SetActivation 方法中放置一个消息框,线程就会阻塞并且窗口的进度指示器会更新。我了解基本的线程,但是整个 Dispatcher 对我来说都是新的。我错过了什么?

更新:它现在似乎正在工作。事实证明,进度更新得太快了,以至于它从未显示在屏幕上。但是,我仍然想了解为什么 Dispatcher.Invoke 完成了(这是我没有编写的现有代码)。为什么操作内容不与 *.xaml.cs 代码的其余部分一致?

最佳答案

您的最后一段提到线程两次,这增加了存在一个或多个后台线程的可能性。但是由于您没有提到应用程序中存在哪些线程、它们是如何创建的、它们如何交互等,我暂时假设只有一个线程。

如果 UI 线程是唯一的线程,问题就很明显:您的 UI 线程正忙于运行正在进行的任务,而没有花时间呈现更新后的 UI。如果这是问题所在,这可能会解决它:

viewModel.ActivationInProgress = activateInProgress; 
Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle,
                       new Action(() => {}));

BeginInvoke 强制所有高于输入优先级的 Dispatcher 操作在当前线程继续之前完成。

关于c# - 为什么 Dispatcher.Invoke 不触发 UI 更新?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3041798/

相关文章:

c# - 单链表C#中的基数排序

c# - 像 Google Chrome 选项卡一样的选项卡控件?

C# 如何从 calendar.SelectedDate 中以 dd/MM/yyyy 格式获取日期

url - 如何在cherrypy中获取对象的url?

wpf - 在 Microsoft 显示错误消息之前在 Word 加载项中捕获 C# WPF 未处理的异常

c# - 为什么向列表<>添加新值会覆盖列表<>中的先前值

c# - 如何使用 AutoMapper 将子对象列表转换为字符串列表或 Guid 列表

C# ASP.NET DataGrid 复选框

c# - C#/WPF 中的分散式聊天功能?

c# - 当我们使用双流时,GUI会卡住