views:

146

answers:

2

Is there any essential difference between this code:

ThreadStart starter = new ThreadStart(SomeMethod);
starter.Invoke();

and this?

ThreadStart starter = new ThreadStart(SomeMethod);
Thread th = new Thread(starter);
th.Start();

Or does the first invoke the method on the current thread while the second invokes it on a new thread?

+13  A: 

They are not the same.

Calling new ThreadStart(SomeMethod).Invoke() will execute the method on the current thread using late binding. This is much slower than new ThreadStart(SomeMethod)(), which is in turn a little bit slower than SomeMethod().

Calling new Thread(SomeMethod).Start() will create a new thread (with its own stack), run the method on the thread, then destroy the thread.

Calling ThreadPool.QueueUserWorkItem(delegate { SomeMethod(); }) (which you didn't mention) will run the method in the background on the thread pool, which is a set of threads automatically managed by .Net which you can run code on. Using the ThreadPool is much cheaper than creating a new thread.

Calling BeginInvoke (which you also didn't mention) will also run the method in the background on the thread pool, and will keep information about the result of the method until you call EndInvoke. (After calling BeginInvoke, you must call EndInvoke)

In general, the best option is ThreadPool.QueueUserWorkItem.

SLaks
Why was this downvoted?
SLaks
It not really valid to say that one of the options is better than the others. They do different things. ThreadPool threads are for high-turnover, finite work items. New threads are when you want a new thread. (however, I was not the down-voter)
Kennet Belenky
+1 from me. Awesome explanation.
Charlie Salts
@Kennet: That's why I wrote **In general**. However, you should only make a new thread if you need the `Thread` object, if you need STA, or if it will run for a very long time. Also, it was downvoted before I wrote that.
SLaks
Thanks, SLaks. ThreadPool is exactly what I want - I was creating new Threads to repeatedly execute a short-lived task, and it sounds like the ThreadPool is a more appropriate choice for this.
MusiGenesis
@MusiGenesis: Exactly.
SLaks
Well, ThreadPool works great, except it exposed a different problem. Basically, I'm using these threads to load up audio buffers and play them with the waveOutWrite API method, because you can't call waveOutWrite directly from a waveOut callback. This works fine, except that I now need to also occasionally call the waveOutGetPosition method. Apparently, if I call this method from one thread while waveOutWrite is called from a different thread (which happens randomly) I get a deadlock and my app hangs.
MusiGenesis
I think what I need is a single Thread that I create once and then Invoke repeatedly to execute the waveOutWrite method. I could then safely call waveOutGetPosition from this same Thread, although I'm not sure how to do that. If, say, I want to click a button on my form, get the wave position and display it in a label, how do I do that? If I just call the method, it will execute on the UI thread, which is different from the thread calling waveOutWrite.
MusiGenesis
I can ask this as a separate question if you like. :)
MusiGenesis
+2  A: 

In case SLaks' answer is not totally clear:

does the first invoke the method on the current thread while the second invokes it on a new thread?

Yes.

Foole
I thought that was clear.
SLaks
Sometimes too much information is overwhelming, so I gave the option of a direct answer to his question. I upvoted your answer btw.
Foole