27

I am still kind of new to C#, and especially threading in C#. I am trying to start a function that requires a single threaded apartment (STAThread)

But I am not able to compile the following code:

The function looks as follows in a separate class called MyClass:

internal static string DoX(string n, string p)
        {
            // does some work here that requires STAThread
        }

I have tried the attribute [STAThread] on top of the function but that does not work.

So I am trying to create a new Thread as follows:

 Thread t = new Thread(new ThreadStart(MyClass.DoX));

but this will not compile (The best overloaded method has invalid arguments error). However the example online is very similar (example here) What am I doing wrong and how can I simply make a function run in a new STA thread?

Thanks

Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
Saher Ahwal
  • 9,015
  • 32
  • 84
  • 152
  • "Apply this attribute to the entry point method (the Main() method in C# and Visual Basic). It has no effect on other methods. To set the apartment state of threads you start in your code, use the Thread.SetApartmentState method before starting the thread." - from the MSDN page you linked - does that help? – Blorgbeard Jul 27 '12 at 04:58
  • Before that's what I was doing in my main method but now I have a service and the methods are operation contracts hosted on endpoint and there is no more main methods there since I have a WCF client calling from cmdlets – Saher Ahwal Jul 27 '12 at 05:02
  • It will be fine if the commandlet I am using to call the function to start in STAThread. is that possible? – Saher Ahwal Jul 27 '12 at 05:05
  • I'm not sure how that works - I tagged your question with WCF; I think you need someone who's more familiar with it than me :) – Blorgbeard Jul 27 '12 at 05:08
  • ok thanks. I need to create the thread first and then call Thread.SetApartmentState. So do you know how to create a Thread ? (this is independent of WCF) I am just getting a compile error I don't understand why since I am following the examples – Saher Ahwal Jul 27 '12 at 05:11

1 Answers1

54
Thread thread = new Thread(() => MyClass.DoX("abc", "def"));
thread.SetApartmentState(ApartmentState.STA);
thread.Start();

If you need the value, you can "capture" that back into a variable, but note that the variable won't have the value until the end of the other thread:

int retVal = 0;
Thread thread = new Thread(() => {
    retVal = MyClass.DoX("abc", "def");
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();

or perhaps simpler:

Thread thread = new Thread(() => {
    int retVal = MyClass.DoX("abc", "def");
    // do something with retVal
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • Can you be more specific about `SomethingToDo` please. This is the part where I am not able to build/compile – Saher Ahwal Jul 27 '12 at 05:12
  • @Saher I changed that to the `MyClass.DoX` as per your example; the key point is: that must be a void/parameterless method, i.e. `public void DoX() {...}`; if `MyClass` is a *variable*, `DoX` must be an instance method; if `MyClass` is a *type*, `DoX` must be a static method – Marc Gravell Jul 27 '12 at 05:12
  • @Saher are you joking? Does myClass.DOX (static method, obviously) have the right signature for ThreadStart as per documentation? – TomTom Jul 27 '12 at 05:13
  • but what if I need the parameters? – Saher Ahwal Jul 27 '12 at 05:14
  • by the way, what if I need the returned value from function, how can I do that? Thanks again – Saher Ahwal Jul 27 '12 at 05:18
  • 2
    @MarcGravell Shouldn't there be `thread.Join()` at the end? Otherwise no value returned. – Mr. Blond Aug 06 '16 at 19:36
  • 3
    @EdgarsŠturms no value is "returned" in ether vase; however, the question was how to *start* such a thread. Adding a `Join` at the end could easily confuse casual readers into thinking that it was normal and expected to start and join a thread in close proximity, when actually that is very rare (and usually means you shouldn't be using a thread in the first place, although STA is arguably a good exception to this rule) – Marc Gravell Aug 09 '16 at 09:25