Reputation: 3442
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
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
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
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