views:

6899

answers:

2

I think I need some clarifications regarding WPFs Dispatcher.Invoke and Dispatcher.BeginInvoke usage.

Suppose I have some long running 'work' code like such that is invoked on the press of a button in a simple WPF application:

longWorkTextBox.Text = "Ready For Work!";
Action workAction = delegate
    {
    Console.WriteLine("Starting Work Action");
    int i = int.MaxValue;
    while (i > 0)
        i--;
    Console.WriteLine("Ending Work Action");
    longWorkTextBox.Text = "Work Complete";
    };
longWorkTextBox.Dispatcher.BeginInvoke(DispatcherPriority.Background, workAction);

This code is locking up my user interface while the workAction is being performed. This is because Dispatcher invokes always run on the UI thread, right?

Assuming this, what is the best practice for configuring my dispatcher to execute the workAction in a separate thread from my UI? I know I can add a BackgroundWorker to my workAction to prevent my UI from locking as such:

longWorkTextBox.Text = "Ready For Work!";
Action workAction = delegate
{
    BackgroundWorker worker = new BackgroundWorker();
    worker.DoWork += delegate
    {
        Console.WriteLine("Starting Slow Work");
        int i = int.MaxValue;
        while (i > 0)
        i--;
        Console.WriteLine("Ending Work Action");
    };
    worker.RunWorkerCompleted += delegate
    {
        longWorkTextBox.Text = "Work Complete";
    };
    worker.RunWorkerAsync();
 };
 longWorkTextBox.Dispatcher.BeginInvoke(DispatcherPriority.Background, workAction);

Is there any more elegant ways of doing this besides using the BackgroundWorker? I've always heard that the BackgroundWorker is quirky, so I am curious to know of some alternatives.

+7  A: 

I honestly think the BackgroundWorker is the most elegant solution for this. I cannot think of a simpler way to do it.

Charlie
Yep. You want to do something in a background thread, but affect the UI thread when you are finished, BackgroundWorker is pretty much the easiest thing to use.
Anderson Imes
+2  A: 

Charlie's answer is what you are looking for, really.

However, if it's possible you might look at whether or not you can parcel up your work so that the individual units of work are small and don't affect the UI as much. This would allow you to just use the Dispatcher directly. There is a good example of this on the WPF Threading page: http://msdn.microsoft.com/en-us/library/ms741870.aspx

Anderson Imes
Awesome article on the subject!
Matthew Ruston
Yeah... usually MSDN is the bare-minimum, but that article is really thorough.
Anderson Imes
for further info about async programming in WPF you can read: http://www.a2zdotnet.com/View.aspx?Id=93.
frameworkninja