2
votes

I've implemented the solution from Stack Overflow question Implement progressbar in this simple WPF application.

MainWindow has its own viewmodel. Inside that viewmodel I receive the user's input and consume the WCF service using a background worker. After WCF serves the data back, I'm trying to display it in a new window. This is where the error occurs:

The calling thread must be STA, because many UI components require this.

I tried to put the [STAThread] attribute on the MainWindow code-behind as well as inside the MainWindowViewModel contructor. In both cases nothing changed.

What am I missing?

Update After user clicks command in viewmodel call LoadData method

private void LoadData(string searchBy)
{
    IsBusy = true;
    BackgroundWorker worker = new BackgroundWorker();
    worker.DoWork += (o, ea) =>
    {
        switch (searchBy)
        {
            // WCF call to load data
        }
    }

    worker.RunWorkerCompleted += (o, ea) =>
    {
       IsBusy = false;
    };

    worker.RunWorkerAsync();
2
Where are you creating the BackgroundWorker?Douglas
the "calling thread" in the message is not your UI thread. It is the WCF callback thread. You need to marshal the call from that background thread to your UI thread using Dispatcher, SynchronizationContext etc.treehouse
@Douglas I'm creating BackgroundWorker after button click to load data using wcf call.user1765862
@KaiWang can you pleae post concrete code.user1765862

2 Answers

7
votes

There are numerous duplicates of this issue on Stack Overflow. For example, this question.

Bottom line - any time you create UI components, you must use a single-threaded apartment (STA) thread. Background workers are not STA. Therefore, you cannot create UI components in background workers. You cannot update UI components from background workers. Background workers are designed to run in the background (big surprise there), possibly to crunch data and return a result later on.

4
votes

I think you need to use Application.Current.Dispatcher.BeginInvoke(action). This is to update the UI from a background thread.