Reputation: 182
I have a function that imports data from a database and populates a DataGridView (winform) within a WPF application.
Originally I had the application call the function through it's main thread. Performance was running at around 10 seconds per 1,000 rows, which is significantly longer than I would like it to be. However, because of the use of the application it doesn't really matter how long it takes so I wasn't too worried about improving the speed.
What I was trying to do was make the rows populate as they come in by using a BackgroundWorker to retrieve the rows, then invoke the BackgroundWorker to add the rows as they come in + provide a progress bar.
I was fiddling around and decided to just invoke the entire method, and now the time it takes to import the datarows is more like 1 second per 1,000 rows.
My code looks something like this:
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...
});
}
Any ideas on why I would receive such a spike in performance? It was my understanding that the this.Dispatcher.BeginInvoke((Action)delegate() {}); command runs anything that follows on the main thread, which is what I was previously doing with the 10sec/1,000 rows performance. Is creating a BackgroundWorker allocating more processing speed / cores or something of the like?
I just have no idea why this would happen.
Upvotes: 1
Views: 552
Reputation: 17001
Based on your comments the previous version of the code was adding a row to the datagrid inside the update loop. Adding a row to a grid control has a lot of overhead, mostly from the control repainting its self.
Calling .BeginInvoke on a form doesn't actually do the work immediately, it just queues the work on the UI thread and returns immediately. This small change is allowing your update logic to run at full speed on a different thread from the UI updates. You essentially separated the logic from the presentation, allowing each one to run asynchronously with each other.
Upvotes: 1