Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to run something in the STA thread?

Tags:

c#

.net

wpf

sta

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     [..] } 
like image 727
stiank81 Avatar asked Mar 04 '10 09:03

stiank81


1 Answers

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!

like image 136
Arcturus Avatar answered Sep 30 '22 12:09

Arcturus