Wednesday, February 03, 2010

Multithreaded UI: HostVisual

In general, objects in WPF can only be accessed from the thread that created them.  Sometimes this restriction is confused with the UI thread, but this is not true, and it is perfectly fine for objects to live on other threads.  But it is not generally possible to create an object on one thread, and access it from another.  In almost all cases this will result in an InvalidOperationException, stating that “The calling thread cannot access this object because a different thread owns it.”

Freezables

Of course, there are exceptions to this restriction.  A familiar one is the Freezable class.  Freezable objects can be frozen, at which point they become read-only and we lift the single-thread restriction.  Examples of frozen Freezables include the standard brushes, available from the Brushes class.  These brushes can be used on any thread at any time.

This is incredibly useful, and used for all of the graphics primitive resources (pens, brushes, transforms, etc).  You can even derive your own types from Freezable and play by the same rules.

Separate Windows

Unfortunately, that read-only restriction can be a real problem.  There are many scenarios where we want to run separate pieces of the UI on separate threads.  If these pieces of UI are independent from each other, you can host them in separate windows, and run the windows on separate threads.  This can be a reasonable solution for some scenarios, especially scenarios where the separate threads can be run in independent top-level windows.  The big restriction for this approach is that the graphics from one cannot be composited with the graphics of the other.  So while you could use a child window for the other thread’s UI, the system will just render one on top of the other.  You cannot have transparency, you cannot use one as a brush for 3D content, you can’t draw over it, etc.

Read more: Presentation Source

Posted via email from jasper22's posterous