【问题标题】:Reflect changes in WPF application dynamically动态反映 WPF 应用程序中的变化
【发布时间】:2015-09-23 17:29:46
【问题描述】:

我正在运行一个 WPF 应用程序并想做这样的事情:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        TextBox textBox = new TextBox();
        mainGrid.Children.Add(textBox);
        textBox.Text = "one";
        Thread.Sleep(1000);
        textBox.Text = "two";
        Thread.Sleep(1000);
        textBox.Text = "three";
        Thread.Sleep(1000);
        textBox.Text = "four";
    }
}

在所有这些处理完成之前,显示器不会加载,因此在运行上述代码后,我有一个空白的、无响应的应用程序,直到 3 秒和一个带有单词 4 的文本框。

我查看了 BackgroundWorker 类并尝试了这个:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        // Set up background worker object & hook up handlers
        BackgroundWorker backgroundWorker;
        backgroundWorker = new BackgroundWorker();
        backgroundWorker.DoWork += new DoWorkEventHandler(bgWorker_DoWork);
        backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgWorker_RunWorkerCompleted);

        backgroundWorker.RunWorkerAsync();
    }

    private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() =>
        {
            TextBox textBox = new TextBox();
            mainGrid.Children.Add(textBox);
            textBox.Text = "one";
            Thread.Sleep(1000);
            textBox.Text = "two";
            Thread.Sleep(1000);
            textBox.Text = "three";
            Thread.Sleep(1000);
            textBox.Text = "four";
        }));
    }

    private void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        Debug.WriteLine("done");
    }

仍然是相同的行为。我想在后台/不同线程中运行一些任务,这些任务将在执行过程中对 UI 元素进行更改,我希望这些更改立即反映在显示中。

【问题讨论】:

    标签: c# wpf


    【解决方案1】:

    考虑改用asyncawait

    private async void Window_Loaded(object sender, RoutedEventArgs e)
    {
        TextBox textBox = new TextBox();
        mainGrid.Children.Add(textBox);
        textBox.Text = "one";
        await Task.Delay(1000);
        textBox.Text = "two";
        await Task.Delay(1000);
        textBox.Text = "three";
        await Task.Delay(1000);
        textBox.Text = "four";
    }
    

    这是一个相当不错的tutorial

    【讨论】:

    • 我试图了解 async 和 await 是如何工作的。我找到了这个答案:stackoverflow.com/a/7615440/2136312 但是不明白这个,程序确实在等待异步调用完成。那么这与常规等待有什么不同呢?为什么添加异步会使 GUI 响应?
    • 简而言之,async/await 编程只是写Tasks 的一种更简单的方式。它允许 UI 通过在后台运行任务来保持响应。任务完成后,它将继续执行代码。有关更深入的解释,请参阅here
    【解决方案2】:

    我同意之前的海报,但是如果您想使用后台工作人员,请考虑查看本教程:http://www.wpf-tutorial.com/misc/multi-threading-with-the-backgroundworker/

    [...] 被称为 DoWork 并且一般规则是您不能通过此事件触摸 UI 中的任何内容。相反,您调用 ReportProgress() 方法,该方法反过来引发 ProgressChanged 事件,您可以从中更新 UI。完成后,将结果分配给工作人员,然后引发 RunWorkerCompleted 事件。

    基本上,UI 需要在 一个 线程上运行。否则你就失去了意义。

    【讨论】:

      【解决方案3】:

      async await 可能是最好的答案,但是在这种情况下也可以使用计时器。

          System.Timers.Timer t;
      
          private void Window_Loaded(object sender, RoutedEventArgs e)
          {
              t = new System.Timers.Timer();
              t.Elapsed += t_Elapsed;
              t.Interval = 1000;
              t.Start();
          }
      
          int tickCount = 0;
      
          void t_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
          {
              tickCount++;
              switch (tickCount)
              {
                  case 1: textBox.Text = "one"; break;
                  case 2: textBox.Text = "two"; break;
                  case 3: textBox.Text = "three"; break;
                  case 4: textBox.Text = "four"; break;
                  case 5: t.Stop(); break;
              }
      
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-11
        • 1970-01-01
        • 2021-07-01
        • 1970-01-01
        相关资源
        最近更新 更多