2

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();
Community
  • 1
  • 1
user1765862
  • 13,635
  • 28
  • 115
  • 220
  • Where are you creating the `BackgroundWorker`? – Douglas Jan 12 '14 at 17:25
  • 1
    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 Jan 12 '14 at 18:02
  • @Douglas I'm creating BackgroundWorker after button click to load data using wcf call. – user1765862 Jan 12 '14 at 21:55
  • @KaiWang can you pleae post concrete code. – user1765862 Jan 12 '14 at 21:59
  • possible duplicate of ["The calling thread must be STA, because many UI components require this" error when creating a WPF pop-up Window in thread](http://stackoverflow.com/questions/2657212/the-calling-thread-must-be-sta-because-many-ui-components-require-this-error) – theMayer Jan 12 '14 at 23:39

2 Answers2

7

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.

Community
  • 1
  • 1
theMayer
  • 15,456
  • 7
  • 58
  • 90
  • So, when background worker needs some user interaction, there is no way to get it? – Arman Hayots Aug 19 '15 at 10:40
  • A background worker by definition does not require user interaction. You have a logical problem with your design that needs to be resolved. – theMayer Aug 19 '15 at 10:42
4

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

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
qamar
  • 1,437
  • 1
  • 9
  • 12