【发布时间】: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