Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing UI Control from BackgroundWorker Thread

I have a button on my windows form that calls the RunWorkerAsync() method, this in turn performs an action which then updates a ListBox on the same form.

After the DoWork event has finished I assign the Result for the event (Which is a list), I process the RunWorkerCompleted() event and then perform the following code to update my Listbox

alt text

which calls this:

alt text

(Apologies, code formatting won't work)

Now when I run the application and press the refresh button the following exception appears:

alt text

How would I get around this?

Edit:

The exception is thrown on the folowing statement, this occurs in the DoWork method where I clear the contents to keep the list up to date;

listBoxServers.Items.Clear();

like image 959
Jamie Keeling Avatar asked Dec 13 '10 12:12

Jamie Keeling


2 Answers

Here's a snippet which I find very handy:

public static void ThreadSafe(Action action)
{
    Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Normal, 
        new MethodInvoker(action));
}

You can pass it any delegate of Action type or simply a lambda like this:

ThreadSafe(() =>
{
    [your code here]
});

or

ThreadSafe(listBoxServers.Items.Clear);
like image 68
Nobody Avatar answered Oct 24 '22 18:10

Nobody


You may not call Invoke on the list box, but on the form. For WinForms applications I use something like:

...
this.Invoke((MethodInvoker)delegate()
{
    // Do stuff on ANY control on the form.
});
...

Depending on the .NET version, you may have to declare a delegate for MethodInvoker yourself as

public delegate void MethodInvoker();

However, you might also consider using the ReportProgress feature of the Background Worker. The respective event handler should be called in the context of the form's thread.

like image 28
Thorsten Dittmar Avatar answered Oct 24 '22 20:10

Thorsten Dittmar