2

I tried following:

var task = new Task(() =>
    {
       for (int i=0; i<10; i++) {
          //Create new Grid HERE
          // Add Table with some dynamic data here..
          // print the above Grid here.
        }

    });

task.ContinueWith((previousTask) =>
    {
        label.Content = printerStatus(); // will return "Out of Paper", "printing", "Paper jam", etc.
    },
    TaskScheduler.FromCurrentSynchronizationContext());

label.Content = "Sending to printer";

It returns following error: The calling thread must be STA, because many UI components require this..

The error occurs when it tries to create a new UI object Grid.

How can i fix this? Let me know if there is any other way arround!

3 Answers 3

4

You cannot create UI objects on different thread than the main UI thread because as soon as you add them to the UI, it tries to set the Parent property, and a thread in WPF cannot modify objects that were created on a different thread.

Instead, I'd recommend creating a list or collection of the Grid's Data on the 2nd thread, and binding it to the UI using something like an ItemsControl. This will keep all UI objects on the main UI thread, while background processing can be done on a background thread.

To update a UI object from a background thread, such as your status label, I'd recommend using the Dispatcher like lawrencealan's answer suggests. The Dispatcher is WPF's internal message queue for the main UI thread

Sign up to request clarification or add additional context in comments.

1 Comment

possible to add any examples for this?
2

Tasks use thread pool threads, which are in a MTA.

If you want a background STA thread, you will have to create one yourself and explicitly set the ApartmentState.

Thread t = new Thread( ... );
t.SetApartmentState( ApartmentState.STA );
t.Start();

4 Comments

can you show me the sample code. I am very new to this technology.
And how can i know the task is complete using this?
I suggest reading Joe Albahari for the basics. You have to use Threads not Tasks if you want an STA, so you don't have ContinueWith. You will have to use Dispatcher.Invoke from inside your thread method instead.
@user995387 - Unless you report the progress of the thread, you have no way of knowing when the thread will be completed, thats entirely up the the scheduler.
1

Using the Dispatcher for the label and Invoke might help:

label.Dispatcher.Invoke(
      System.Windows.Threading.DispatcherPriority.Normal,
      new Action(
        delegate()
        {
          label.Content = printerStatus();
        }
    ));

5 Comments

It is not able to create Grid! it shows error in Grid object whlie creating it.
What do you mean by grid, you mean DataGridView or Simple Grid data structure.
WPF Grid. that holds the UI contents..msdn.microsoft.com/en-us/library/system.windows.controls.grid.aspx
When modifying any sort of UI objects that are not created in the same thread, from within another thread or background worker, you need to use a Dispatcher. I think maybe your Grid creation is another problem, unless you are attempting to modify an existing UI object.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.