Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"The calling thread must be STA, because many UI components require this." when adding ListView items dynamically using BeginInvoke

I am trying to call a method from BackgroundWorker that adds a user control to ListView:

private void AddItems(List<FileItem> fileItems) {
    System.Threading.Thread.CurrentThread.SetApartmentState(System.Threading.ApartmentState.STA);
    Dispatcher.BeginInvoke(new Action(() => files.ItemsSource = fileItems));
}

The user control files is getting the data from fileItems successfully in its constructor but it's throwing The calling thread must be STA, because many UI components require this. exception. I already tried adding [STAThread] attribute to all parent methods one by one but still it's throwing the exception. Where should I add this attribute?

UPDATE

Please also note that Dispatcher.BeginInvoke(new Action(() => files.Items.Clear())); is executing correctly.

like image 261
Aishwarya Shiva Avatar asked Feb 14 '26 06:02

Aishwarya Shiva


1 Answers

This Dispatcher refers to one associated with the BGW thread, not the WPF/UI thread. By default a new dispatcher/context will be created if none is associated with the current thread; in context this is entirely useless.

If supplying the dispatcher instance (Dispatcher.CurrentInstance) from the UI thread that starts the BGW then it 'ought to work'. Likewise, as Hans points out, the correct (WPF/UI) dispatcher object should be accessible through the dispatcher associated with the Application.

Additionally an arbitrary object can be supplied in the ReportProgress method; this allows sending information back to the parent. The processing of the UI components can then done in the event handler which is automatically run on the correct WPF/UI thread. (The same holds for 'work complete' processing.)

There is no need to set any STA threading options/attributes for a standard WPF project.

like image 62
user2864740 Avatar answered Feb 15 '26 19:02

user2864740