Core_F
Core_F

Reputation: 3442

Event in the wrong thread?

I have a question about threading.

I have a WPF application, that should show the status of some queries. For this I have created a class, that runs multiple queries in multiple thread (backgroundworker). I've also created an event, so I can react while the queries are running.

    private void cmdStart(object sender, RoutedEventArgs e)
    {
        QuerySetup qs = new QuerySetup();
        //Filling qs with some data
        //...
        SqlProxy sql = new SqlProxy();
        sql.QueryCompleted += new SqlProxy.QueryCompletedEventHandler(sql_QueryCompleted);

        //Starts the backgroundworker
        sql.RunSQL(qs);
    }

    private void sql_QueryCompleted(QueryResult qr)
    {
        lstStatus.Items.Clear();
        lstStatus.Items.Add(qr.RuntimeTotal);
        //... and some more...
    }

Now I get an error message that tells me, that I can't access lstStatus because it's owned by a different thread.

But why? Shouldn't the event be in the same thread as the GUI? How can I solve my problem?

Upvotes: 1

Views: 874

Answers (3)

aamir
aamir

Reputation: 21

Dispatcher.BeginInvoke always helps in updating controls from other threads. Also, if you are using Backgroundworker class and raising the event from DoWork, eventhandlers are raised on the DoWork thread. If you raise the event from WorkCompleted event of Backgroundworker, it will be raised on the thread from where you started the Backgroundworker, that can be your UI thread (no need of Dispatcher here). Same is true for Backgroundworker.ProgressChanged event.

Upvotes: 1

Justin Niessner
Justin Niessner

Reputation: 245489

No, the event will not be executed on the UI thread.

It's easy to work around though, you should have to invoke your code that interacts with GUI elements on the UI Thread:

private void sql_QueryCompleted(QueryResult qr)
{
    Dispatcher.BeginInvoke(new Action(() => { 
        lstStatus.Items.Clear();
        lstStatus.Items.Add(qr.RuntimeTotal);
        //... and some more...
    });
}

Upvotes: 2

SLaks
SLaks

Reputation: 888167

No.
Most non-UI components will raise callbacks in non-UI threads (typcially ThreadPool threads)

You can call Dispactcher.BeginInvoke to run code on the UI thread:

Dispactcher.BeginInvoke(new Action(delegate {
    ...
}));

Upvotes: 5

Related Questions