Multithreaded, Multi-Dispatcher WPF app still draws in a single thread?

I have a WPF & C# app that contains a large DataGrid, about 35 cols x 50 rows, to monitor a bunch of frequently changing values. The trouble is, when the whole grid is visible, refreshing it hangs up the user interface for almost a second. I refresh it explicitly every two seconds, which is fine for what I'm doing, but having the rest of the UI hang up is a real pain.

OK, so I decide I'll run the rest of the UI in a separate window in a separate thread with a separate Dispatcher. I wrote a toy window containing just a textBlock with an incrementing count that updates 10 times a second using a DispatcherTimer. However, rather than the count incrementing smoothly, it pauses while the grid refreshes, then resumes displaying with the count about 10 higher than it was when it paused, so timer events are getting handled. I'm just not seeing a refresh.

Does WPF only draw all its elements in a single thread? Any way around it?

Here's my 2nd window creation code:

private void Window_Loaded( object sender, RoutedEventArgs e )
{
    ThreadStart ts = new ThreadStart( RunSpareThread );
    m_spare_thread = new Thread( ts );
    m_spare_thread.IsBackground = true;
    m_spare_thread.Priority = ThreadPriority.Highest;
    m_spare_thread.SetApartmentState( ApartmentState.STA );
    m_spare_thread.Start();

    Dispatcher.Thread.Priority = ThreadPriority.Lowest;
}

void RunSpareThread()
{
    m_spare_window = new SpareWindow();
    m_spare_window.Show();
    Dispatcher.Run();
}

FYI I've tried implementing the grid a few different ways - as a ListView, as a Canvas that overrides OnRender and draws a whole bunch of GlyphRunDrawings - WPF is just incredibly slow at drawing this stuff.

Answers


Unfortunately yes. That said there are a number of things you can do to increase the responsiveness of your ui. One of the main things is to make sure that the least amount of work is being done in the UI thread. This means doing all of the DB reading etc. within a separate context. You should also look into how your grid is displaying your values - is it virtualizing? Then there is also how you are databinding, a bindingsource should allow you to only update the binding after all of the changes are finished.


WPF is very fast if you use it properly.

Some tips:

  1. Implement model (or ViewModel in terms of MVVM) of the data you want to display. Be sure that it implements INotifyPropertyChanged interface. Bind collection of such models to your DataGrid;
  2. Do not refresh all data each N seconds. You should somehow detect data changes (using working thread) and update appropriate properties on appropriate models. Because of data binding, all changes will be automatically reflected on the DataGrid. So, you don't even need to use Dispatcher (at least explicitly);
  3. Use ListView instead of DataGrid if you don't need to do special actions with data (like editing, sorting, filtering, etc.);
  4. Consider implementation of a virtualization if you need to display a huge amount of rows.

Need Your Help

MongoDB Administration

javascript mongodb csv

I am trying to import a simple CSV file using mongoimport. The command I used was

MVC 3 Entity Data Model not picking up Foreign Keys

asp.net-mvc asp.net-mvc-3 entity-framework associations ado.net-entity-data-model

I am returning to programming after focusing on databases for a number of years. I used to be a gun in VB6 but .Net has me floundering.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.