I have to build a desktop application and decided it was about time I played with Windows Presentation Foundation because it has some exciting options when it comes to building applications. The basic concept for this application is that it will run all the time and use background worker threads to accomplish various tasks.
I had to learn how WPF manages the display thread. I am typically a web developer so I don’t often work in a multi-threaded environment for desktop applications. I knew I needed a thread that managed the display of each object but I didn’t know how to pump those messages back to the display object from my background thread. I decided I would research it.
I found that WPF uses something called the Dispatcher which manages the thread that is allowed to update the display. I found a couple of tutorials which walked you through creating new threads using the Dispatcher to spawn those threads. I don’t know how well it worked though because as I tried to add some fake application latency “Thread.Sleep(2000)” the whole display object would sleep for those two seconds. That is not what I wanted at all. This is the code I was using to spawn a new StartApplication Thread.
this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new StartUpApp(StartUpApplication));
Where StartUpApp was my delegate and StartUpApplication was the method that matched the delegate signature.
Anyway, that was failing miserably so I was talking to a friend of mine who’s worked with his own multi-threaded applications and we talked about threading in general. He really didn’t help me along in the process, so I took a short break from what I was working on.
I came back to reading more documentation on the MDSN and realized that the Dispatcher message pump would always push messages back to the display thread. This meant that any Thread that was started could call back to the Dispatcher and send those messages back. So, here is what I finally came up with:
private void StartAppButton_Click(object sender, RoutedEventArgs e)
{
i = 0;
Thread startUp = new System.Threading.Thread(StartUpApplication);
startUp.Start();
}
public delegate void UpdateLabelDelegate(Label lb, string message);
bool shouldContinue = true;
public void StartUpApplication()
{
while (shouldContinue)
{
this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new UpdateLabelDelegate(UpdateLabel), ApplicationStatus, "Checking for job to process");
Thread.Sleep(2000);
this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new UpdateLabelDelegate(UpdateLabel), ApplicationStatus, "Processing newest Job");
Thread.Sleep(2000);
this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new UpdateLabelDelegate(UpdateLabel), ApplicationStatus, "Processing Completed");
}
}
public static void UpdateLabel(Label lb, string message)
{
lb.Content = message;
}
This was exactly what I was looking for. Now that I can pump messages back to the display from the processing thread I can flush out the rest of the functionality of the application.