【问题标题】:Updating UI while running task运行任务时更新 UI
【发布时间】:2010-11-19 10:33:16
【问题描述】:

我有以下代码:

        progressBar1.Minimum = 0;
        progressBar1.Maximum = Results.Count;

        foreach (MyClass cls in Results)
        {                
              progressBar1.Value += 1;

              // Go to DB and get large quantity of data
              cls.GetHistoryData();

        }

我想做的是将处理转移到另一个线程,以便progressBar1 正确更新。我找到了一个article,它暗示我应该可以在进度条上使用 Invoke 方法,但似乎没有。

【问题讨论】:

    标签: c# wpf multithreading invoke


    【解决方案1】:

    如果将进度条绑定到数据属性,则无需手动切换线程上下文。 WPF 绑定引擎会自动为您执行此操作。

    <ProgressBar Value={Binding Progress} />
    

    然后在你的线程中:

    foreach (MyClass cls in Results)
    {                
          // databinding will automatically marshal to UI thread
          this.Progress++;
          cls.GetHistoryData();
    }
    

    在大多数情况下,这比使用 Dispatcher.InvokeBackgroundWorker 自行编组更简洁且不易出错

    【讨论】:

    • 这看起来是理想的解决方案。不幸的是,它似乎不起作用。我假设 Progress 需要设置为类级别变量(否则它无法识别它),我还需要做些什么吗?
    • 这取决于您的设置。您可以像在这篇文章中一样向您的 UserControl/Window 添加一个属性并绑定到它:goo.gl/ZMcnp 或者更理想的是,如果您使用 MVVM(这让很多事情变得更容易!)您将为您的 ProgressDialogViewModel 提供一个 DataTemplate该类有一个 CurrentProgress 属性以及诸如 Message 和 Tiltle 属性之类的东西。在您的 DataTemplate 中,您绑定了这些属性。
    • +1 - 最佳解决方案。但是,我不会为“Progress”实现依赖属性,而是使用 INotifyPropertyChanged。
    • 我没有在任何地方提到依赖属性。我也偏爱INPC
    【解决方案2】:

    您应该检查BackgroundWorker 类。它支持进度并正确处理线程之间的通信。

    【讨论】:

      【解决方案3】:

      你会这样开始一个新线程:

      Thread t1 = new Thread(methodnametocall);
         t1.start();
      
      void methodnametocall()
      {
         this.Invoke((MethodInvoker)delegate
         {
      
              control to update;
          }
      });
      

      【讨论】:

        【解决方案4】:

        试试这个

        progressBar1.Minimum = 0;
        progressBar1.Maximum = Results.Count;
        
        foreach (MyClass cls in Results)
        {
            ThreadPool.QueueUserWorkItem((o) =>
                     {
                         progressBar1.Dispatcher.BeginInvoke(
                             (Action) (() => progressBar1.Value += 1));
                         cls.GetHistoryData();
                     });
        }
        

        【讨论】:

          【解决方案5】:

          您链接到的文章是一个 winforms 示例,但您正在制作一个 WPF 应用程序。在您的情况下,您应该考虑使用 Dispatcher 类,您可以通过控件的 Dispatcher 属性获得。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2017-01-26
            • 1970-01-01
            • 2021-06-12
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多