Just ran across this. Microsoft has released an internal tool called Snippet Designer. This is a Visual Studio 2008 Add-in, and is available from CodePlex. Snippets are invaluable in Visual Studio. Especially with WPF (does anyone really hand code a Dependency Property?). However, creating, editing and managing snippets has never been all that fun. I’ve tried numerous GUI applications that were meant to help you out here, but they never really worked all that well. In the end, I’ve always just resorted to doing things by hand, which works, but is a large enough barrier to entry that I don’t fix little problems in my snippets as often as I should. This tool looks very promising, though it has some issues. For instance, it fails to find my user snippets. It appears the code expects to find a %LocalAppData%\SnippetIndex.xml file, but there is no such thing. Also, when I open a Microsoft supplied snippet, the Error List complains about the snippet expansion macros. That’s sort of a cosmetic issue, but still one that bothers me.
Archive for September, 2008
I can’t recommend this article by Paul Stovell enough. His use of custom controls used to focus on semantic markup instead of UI design is brilliant. We did similar work in a XUL project I worked on, and the amount of developer time this can save is amazing. If you do WPF development, you absolutely should consider using this technique as often as you can.
Writing multi-threaded code is hard. Very hard. Writing multi-threaded UI code is even harder. Much harder. See, user interface components are generally not thread safe. You can’t modify properties or call methods on user interface components safely, unless you’re in the same thread on which the component was created. This has been true on every UI framework I’ve ever dealt with, and it’s true in WPF. This makes it very difficult to create multi-threaded UI code, because you have to constantly be marshalling operations across thread boundaries, which is both more complicated to code, and leads to the potential for race conditions and deadlocks.
WPF has helped to make the marshalling of operations across thread boundaries a little easier with the DispatcherObject class. DispatcherObject is generally used as a base class for other types, and all of the WPF UI components derive from DispatcherObject. When a DispatcherObject is constructed, it associates itself with the currently running thread. A couple of methods, CheckAccess and VerifyAccess, allow you to determine if the current thread is the same thread that the DispatcherObject was created on. CheckAccess simply returns a boolean, while VerifyAccess will throw an exception if the current thread isn’t the associated thread on which the DispatcherObject was created. By convention, any property or method that must be called only when running on the associated thread will call VerifyAccess internally, thus ensuring they can’t be called except from the thread on which the DispatcherObject was created.
So, we understand how DispatcherObject ensures that operations occur only on the associated thread. How does it help us to marshal operations onto this thread? DispatcherObject has a Dispatcher property that includes various overloads of Invoke and BeginInvoke that marshal operations onto the DispatcherObject’s associated thread. All of this greatly simplifies the coding required to create objects with thread affinity and to marshal operations across thread boundaries. You should be aware that this isn’t a silver bullet solution. The marshalling can still lead to deadlock. The general idea behind marshalling operations across thread boundaries is to bundle up the operation and put it in a queue where the other thread can extract it and run the operation. This requires the other thread to actually participate by checking the queue and running the operation. If that thread is busy doing something else, it won’t be checking the queue and the operation will be sitting there. So, if one thread is marshalling to another, and that thread is try to marshal to the first, deadlock can ensue. So, you must be careful here, even though the DispatcherObject has made it easier to coordinate between threads.
WinForms had a somewhat similar concept to DispatcherObject in the SynchronizationContext class, though the DispatcherObject is a cleaner and easier to use design. Score one for WPF.
So, with the DispatcherObject or SynchronizationContext classes, it’s possible to create background operations that communicate with our UI by marshalling operations onto the "UI thread" (the thread on which the UI components are created). However, there’s still a lot of dirty little details you have to take into account when creating such a background process. So, WinForms provided us with a BackgroundWorker class. This class would greatly simplify the code required to create a background task, allow it to be cancelled and report progress on the UI thread. WPF doesn’t have a similar concept, so score one for WinForms.
Other people have pointed out that you can use the BackgroundWorker in a WPF application, and there’s plenty of examples of how to do this. It’s not rocket science, really, so I’m not going to cover that. What I am going to do, and the whole purpose of the post, is tell you that BackgroundWorker is a sub-optimal solution in WPF, and provide you with the basis of a better solution.
Why is BackgroundWorker sub-optimal? Because the design requires you to use an event handler in order to update your UI on the progress of the operation. This is WPF. We don’t want to have to write an event handler that will update our UI. We want to use data binding and no code at all!
This is fairly easy to achieve. I’m not going to provide code for this here, because I’m still working on the concept. But it should be easy enough for you to take the idea I’m about to describe and run with it.
What I’m working on is what I’m calling a BackgroundTask. This is a class that works very similarly to the way the BackgroundWorker does. However, there is no ProgressChanged event on the BackgroundTask. Instead, there’s a PercentProgress property which the UI can data bind to. BackgroundTask is a DispatcherObject, so it has thread affinity, and by convention should be created on the "UI thread". The background process will then use the magic of DispatcherObject to marshal changes to the PercentProgress property onto the UI thread, where INotifyPropertyChanged can notify the data binding that it needs to be updated.
This is a very simple concept, but the result is a much easier to use component in WPF. More importantly, this is just the tip of the iceberg for what’s possible with the idea. Imagine we give these BackgroundTask objects a Title property that can also be used in data binding to display on the UI. Then imagine a BackgroundTaskCollection that holds running BackgroundTask instances (which would be automatically removed from the collection when the task completes). Now our UI can display information about multiple running background tasks through simple WPF data binding magic. Now imagine we have other properties on the BackgroundTask that can also be used in data binding to display even richer information about our background process. Doesn’t this concept start to sound very exciting?
Now, here’s another huge bonus to this design. Let’s imagine we have some domain model (data model, what ever name you wish to use) objects which our UI displays through data binding. Imagine that these models are not thread safe (they probably shouldn’t be). Then imagine we need to add some long running process that’s going to modify these domain objects. We don’t want to run this process on the UI thread, because it would cause our UI to become unresponsive for an extended period of time. We don’t want to, or can’t, modify the domain object, however, in order to make it thread safe. So, what do we do? Well, you don’t have to do much if you’re using a BackgroundTask concept like I just described. The operation you’re running in the background can use the BackgroundTask to marshal operations that modify the domain object onto the "UI thread". Your UI will update itself through the magic of data binding. Problem solved with a minimal amount of code, and no impact to your current domain object design.