在UI线程中进行计算时的进度窗口

时间:2012-07-16 12:22:58

标签: c# wpf multithreading ui-thread

我想实现这个目标:

  1. 创建一个新窗口,它只是一个旋转加载器和一些静态文本,并显示它。
  2. 在UI线程上做一些计算(必须在那里完成)
  3. 关闭加载程序窗口
  4. 目前,当我在加载器窗口上调用.Show()时,它根本不加载,它只是挂起作为一个空白窗口(UI线程被阻止,我不想要)

    如何在我的计算完成的同时启用加载器窗口来显示其内容?

    private void CopyToClipboard(object sender, RoutedEventArgs e)
        {
            var selected = mDataGrid.SelectedItem;
            var selectedIndex = mDataGrid.SelectedIndex;
            var progressWindow = mProgressDialog.Create(this,"Copying data to clipboard");
            progressWindow.Show();
            try
            {
    
                mDataGrid.ClipboardCopyMode = DataGridClipboardCopyMode.IncludeHeader;
                mDataGrid.SelectionMode = DataGridSelectionMode.Extended;
                mDataGrid.SelectAllCells();  // SLOW !!!!
                ApplicationCommands.Copy.Execute(null, mDataGrid); //SLOW !!!!
            }
            catch (Exception ex)
            {
                mLog.Error("Copying to clipboard", ex);
                MessageBox.Show("Error while copying to clipboard");
            }
            finally
            {
                mDataGrid.SelectionMode = DataGridSelectionMode.Single;
                mDataGrid.UnselectAllCells();
                this.Select(selectedIndex, selected);
                progressWindow.Close();
            }
        }
    

2 个答案:

答案 0 :(得分:1)

正如你所说,你的计算是在UI线程上完成的,这就是为什么你的窗口是空白的,它不是"重新粉刷"由于UI线程忙。

因此,除非你在另一个主题上进行长时间的计算,否则你会陷入困境。

答案 1 :(得分:0)

我唯一能做到的就是:

progressWindow.Show();
this.DoEvents();


public static void DoEvents(this Window _)
    {
        Application.Current.Dispatcher.Invoke(DispatcherPriority.Background,
                                              new Action(delegate { }));
    }

至少显示“加载器窗口”,因此用户知道发生了什么。它通常持续不到一秒钟,所以这个解决方案对我来说是可以接受的。