How to run something in the STA thread?

stiank81 picture stiank81 · Mar 4, 2010 · Viewed 70k times · Source

In my WPF application I do some async communication (with server). In the callback function I end up creating InkPresenter objects from the result from server. This requires the running thread to be STA, which apparently it currently isn't. Therefore I get the following exception:

Cannot create instance of 'InkPresenter' defined in assembly [..] The calling thread must be STA, because many UI components require this.

Currently my async function call is like this:

public void SearchForFooAsync(string searchString)
{
    var caller = new Func<string, Foo>(_patientProxy.SearchForFoo);
    caller.BeginInvoke(searchString, new AsyncCallback(SearchForFooCallbackMethod), null);
}

How can I make the callback - which will do the InkPresenter creation - be STA? Or invoke the XamlReader parsing in a new STA thread.

public void SearchForFooCallbackMethod(IAsyncResult ar)
{
    var foo = GetFooFromAsyncResult(ar); 
    var inkPresenter = XamlReader.Parse(foo.Xaml) as InkPresenter; // <!-- Requires STA
    [..]
}

Answer

Arcturus picture Arcturus · Mar 4, 2010

You can start STA Threads like so:

    Thread thread = new Thread(MethodWhichRequiresSTA);
    thread.SetApartmentState(ApartmentState.STA); //Set the thread to STA
    thread.Start(); 
    thread.Join(); //Wait for the thread to end

The only problem is that your result object must be passed along somehow.. You can use a private field for that, or dive into passing along parameters into threads. Here I set the foo data in a private field and start up the STA Thread to mutate the inkpresenter!

private var foo;
public void SearchForFooCallbackMethod(IAsyncResult ar)
{
    foo = GetFooFromAsyncResult(ar); 
    Thread thread = new Thread(ProcessInkPresenter);
    thread.SetApartmentState(ApartmentState.STA);
    thread.Start();
    thread.Join(); 
}

private void ProcessInkPresenter()
{
    var inkPresenter = XamlReader.Parse(foo.Xaml) as InkPresenter;
}

Hope this helps!