Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Advantage of using Thread.Start vs QueueUserWorkItem

In multithreaded .NET programming, what are the decision criteria for using ThreadPool.QueueUserWorkItem versus starting my own thread via new Thread() and Thread.Start()?

In a server app (let's say, an ASP.NET app or a WCF service) I think the ThreadPool is always there and available. What about in a client app, like a WinForms or WPF app? Is there a cost to spin up the thread pool? If I just want 3 or 4 threads to work for a short period on some computation, is it better to QUWI or to Thread.Start().

like image 442
Cheeso Avatar asked Mar 26 '09 05:03

Cheeso


People also ask

What is the advantage of thread pool in Java?

Advantages of a Thread PoolBetter performance. Saves time. No need to create a thread again and again. Easy to access.

What is the use of ThreadPool QueueUserWorkItem method in C#?

QueueUserWorkItem(WaitCallback, Object) Queues a method for execution, and specifies an object containing data to be used by the method. The method executes when a thread pool thread becomes available.

Should you use a thread pool or just create a new thread whenever you need it?

I would advise you to use a ThreadPool instead of creating a new Thread. You can have a beginning of answer in Oracle's documentation about thread pools.

What is thread pool queue?

In computer programming, a thread pool is a software design pattern for achieving concurrency of execution in a computer program. Often also called a replicated workers or worker-crew model, a thread pool maintains multiple threads waiting for tasks to be allocated for concurrent execution by the supervising program.


6 Answers

The ThreadPool is always there, however, there are a finite number of threads allocated to the pool based on the number of processors. For ASP.NET applications, it is generally a bad idea to use Threads unless you really are starting off an Async process and know that there won't be a large number of requests (remember that there are a finite number of threads in the ThreadPool which you share with everything running in your AppDomain and there is a realistic limit on the total number of threads you want to create using new Thread() as well).

For WinForms apps consider using the BackgroundWorker instead of using a Thread or the ThreadPool. It uses the ThreadPool, however, it makes communicating between threads easier on the multi-thread savvy programmer.

Updated

Avoid using ThreadPool.QueueUserWorkItem as your app pool could disappear at any time. Move this work outside or use WebBackgrounder if you must.

From Hanselman.com - "Checklist: What NOT to do in ASP.NET"

like image 59
CodeMonkeyKing Avatar answered Sep 30 '22 23:09

CodeMonkeyKing


I was gonna make this a comment, but it got too long.
CodemonkeyKing seems to have hit on an important point, though not strongly enough in my opinion.

There are lots of criteria you might use to describe code. Will it be used in a long running app or not? Winforms app or not? Is it a Server or client app? library or standalone exe? etc etc.

Seems to me that if your code will run in a standalone app and you have control over all the surrounding code, then you can roll your own thread pool, start your own threads, and measure and manage the cost around thread startup, thread latency, and resource consumption. Or you could use the QUWI, but it won't kill your app either way. You are free to choose.

On the other hand if your code is packaged as a library that may be used in a server -in ASP.NET, or maybe in a SQL CLR app, or a WCF Service - then it is a really bad idea to create threads. You need to use QUWI, or some other mechanism that exploits the built-in thread pool (like BackgroundWorker). If it is to be used in client-side apps with other libraries, once again, QUWI is required. Imagine that every library wanting to take advantage of multi-core computers rolled their own threads. There would be complete chaos in apps that used more than a few libraries. Rampant threads, all competing for the same resources. No central coordination of #threads vs # processors.

Good hygeine demands that a library, whether it is to be consumed in client apps or server apps, uses the common threadpool, and that means QUWI.

Last thing to realize is this;

A managed thread is either a background thread or a foreground thread. Background threads are identical to foreground threads with one exception: a background thread does not keep the managed execution environment running. Once all foreground threads have been stopped in a managed process (where the .exe file is a managed assembly), the system stops all background threads and shuts down.

Threads that belong to the managed thread pool (that is, threads whose IsThreadPoolThread property is true) are background threads. All threads that enter the managed execution environment from unmanaged code are marked as background threads. All threads generated by creating and starting a new Thread object are by default foreground threads.

If you use a thread to monitor an activity, such as a socket connection, set its IsBackground property to true so that the thread does not prevent your process from terminating.

from the MSDN site.

like image 29
Cheeso Avatar answered Sep 30 '22 23:09

Cheeso


This discussion will interest you
When should I not use the ThreadPool in .Net?

like image 35
Cherian Avatar answered Sep 30 '22 23:09

Cherian


If your tasks are short you will most likely see much better performance by scheduling tasks on the thread pool via QueueUserWorkItem or BeginInvoke as you avoid the repeated cost of creating and destroying your own threads.

The thread pool obviously pays for creating threads as well, but it reuses the threads, so you don't pay the cost per task.

You may also want to take a look at Threading in C# (free ebook).

like image 25
Brian Rasmussen Avatar answered Sep 30 '22 23:09

Brian Rasmussen


Here's another advantage to using ThreadPool.QueueUserWorkItem.

I have a winforms app which has a hearbeat. I originally implemented this using

            heartbeat = new Thread(HeartbeatDoWork);
        heartbeat.Start();

Which works fine 98% of the time. However when the app is closed sometimes it doesn't 'die' properly, ie the process is still visible in task manager.

To be brief, the heartbeat published an event and it was handling the event (CAB pub/sub) where it was 'getting stuck'.

The fix was easy, just change to using this

            ThreadPool.QueueUserWorkItem(HeartbeatDoWork);

I'm sure there's a few extra things I could do when spinning off my own thread and it to would be cleaned up properly, but this is simpler, faster and easier to understand...the ThreadPool does all the work for me.

like image 34
wallismark Avatar answered Sep 30 '22 23:09

wallismark


The thread pool is always available in .NET apps, regardless of what kind.

The cost for starting a thread from the thread pool via ThreadPool.QueueUserWorkItem will be no more than the cost of starting your own thread, and could be less.

If you just want a few threads for a short period, then use the thread pool. That's what it's for.

like image 37
Jim Mischel Avatar answered Oct 01 '22 00:10

Jim Mischel