【问题标题】:Why am I experiencing a huge performance increase while using BackgroundWorker this.Dispatcher.BeginInvoke((Action)delegate()为什么我在使用 BackgroundWorker this.Dispatcher.BeginInvoke((Action)delegate() 时性能大幅提升
【发布时间】:2015-10-06 16:56:08
【问题描述】:

我有一个从数据库导入数据并在 WPF 应用程序中填充 DataGridView (winform) 的函数。

最初我让应用程序通过它的主线程调用该函数。性能以每 1,000 行运行大约 10 秒的速度运行,这比我希望的要长得多。但是,由于使用了该应用程序,因此需要多长时间并不重要,因此我并不太担心提高速度。

我试图做的是通过使用 BackgroundWorker 检索行来使行在它们进入时填充,然后调用 BackgroundWorker 以在它们进入时添加行 + 提供进度条。

我折腾了一下,决定只调用整个方法,现在导入数据行所需的时间更像是每 1000 行 1 秒。

我的代码如下所示:

Window_Loaded() 
{
        dataPopulater = new BackgroundWorker(); // variable declared in the class
        dataPopulater.WorkerReportsProgress = true;
        dataPopulater.DoWork += new DoWorkEventHandler(dataPopulater_DoWorkReadSavedRecords);
        dataPopulater.ProgressChanged += new ProgressChangedEventHandler(dataPopulater_ProgressChanged);
        dataPopulater.RunWorkerCompleted += dataPopulater_RunWorkerCompleted;
        dataPopulater.RunWorkerAsync(startUpRead);
}

private void dataPopulater_DoWorkReadSavedRecords(object sender, DoWorkEventArgs e)
    {
        this.Dispatcher.BeginInvoke((Action)delegate()
            {
              //Import method...
            });
    }

对我为什么会获得如此高的性能有任何想法吗?我的理解是 this.Dispatcher.BeginInvoke((Action)delegate() {});命令运行主线程上的任何内容,这就是我之前在 10 秒/1,000 行性能上所做的。是否正在创建一个 BackgroundWorker 分配更多的处理速度/内核或类似的东西?

我只是不知道为什么会发生这种情况。

【问题讨论】:

  • 你在上一版本的更新方法中完全更新了UI吗?
  • 是的,我是,但之前不是多线程的。我在方法中调用了 DataGridView.Rows.Add(...) 。我现在使用的方法实际上与以前的方法完全相同,唯一的区别是它是通过 BackgroundWorker_DoWork 方法中的调用来执行的。
  • 标准消防软管错误。而不是强制网格为每一行重新绘制自己,它现在只重新绘制一次。 1000 行的工作线程用了 1 秒,而网格只用了 10 秒就赶上了所有那些毫无意义的绘画。当然还有更快乐的媒介,重新平衡工作量。不是一次追加一行,而是一次追加 100 行。或者只是简单地做得更智能、更用户友好,请注意 Google 如何在几分之一秒内呈现数百万次点击。
  • 我错了。我将 Rows 添加到函数中的 DataGridViewRows 列表中,然后在数据完全交互并创建 DataGridViewRow 并将其添加到列表后将 DataGridView 的 DataSource 设置为所述列表。

标签: wpf multithreading backgroundworker begininvoke


【解决方案1】:

根据您的 cmets,之前版本的代码是在更新循环内向数据网格添加一行。向网格控件添加一行会产生很多开销,主要来自控件重新绘制自身。

在表单上调用 .BeginInvoke 实际上并不会立即完成工作,它只是将 UI 线程上的工作排入队列并立即返回。这个小改动允许您的更新逻辑在与 UI 更新不同的线程上全速运行。您基本上将逻辑与演示分开,允许每个逻辑彼此异步运行。

【讨论】:

    猜你喜欢
    • 2013-01-18
    • 2015-10-17
    • 2013-05-24
    • 2011-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多