I know that the CLR gives each AppDomain ThreadPool time slice to work , yet i wanted to know if by creating a new thread like so Thread t = new Thread(...);
Is it managed by the CLR or by the AppDomin ThreadPool ?
Thread t = new Thread(); will not be managed by the ThreadPool. But it is an abstraction provided by the CLR on the Operating System threads. ThreadPool is an addtional abstraction which facilitates reusing threads and sharing thread resources.
Here is an excellent resource on threads in .NET: http://www.albahari.com/threading/
If you're using .NET 4.0 consider using TPL.
When you create threads with the Thread class, you are in control. You create them as you need them, and you define whether they are background or foreground (keeps the calling process alive), you set their Priority, you start and stop them.
With ThreadPool or Task (which use the ThreadPool behind the scenes) you let the ThreadPool class manage the creation of threads, and maximizes reusability of threads, which saves you the time needed to create a new thread. One thing to notice is that unlike the Thread default, threads created by the ThreadPool don't keep the calling process alive.
A huge advantage of using the ThreadPool is that you can have a small number of threads handle lots of tasks. Conversely, given that the pool doesn't kill threads (because it's designed for reusability), if you had a bunch of threads created by the ThreadPool, but later the number of items shrinks, the ThreadPool idles a lot, wasting resources.
When you create new threads they are not managed by the thread pool.
If you create a thread manually then you control its life time, this is independent from the Thread pool.
Related
I have some number of threads dedicated to one task (receive and handle requests) and some number of threads dedicated to other tasks (long running/CPU intensive tasks).
It's a console application.
And I want to use async/await in all of the threads but I learned that async/await uses the managed thread pool to run continuation that means requests handling can be delayed because of a bunch of CPU intensive tasks shown up (yes, so many, it's why i have limited threads count to do this job)?
If i want to limit concurrency, then i must not use TAP?
If i want to do some job in background for aplication's lifetime, then i must not use TAP either?
Should I write a ThradPool implementation with it's own SyncronizationContext to do so?
Is there an other way to run continuation in some set of threads?
And I want to use async/await in all of the threads but I learned that async/await uses the managed thread pool to run continuation that means requests handling can be delayed because of a bunch of CPU intensive tasks shown up (yes, so many, it's why i have limited threads count to do this job)?
This is a close-enough analysis. Technically, it's not async/await that needs the thread pool for continuations, but internal TAP method implementations. That said, it is a common pattern in the BCL, and because of this, exhausting the thread pool can cause delays for asynchronous completion.
If i want to limit concurrency, then i must not use TAP?
As long as you don't overwhelm the thread pool, you can use TAP. Limiting concurrency would free up the thread pool, which will enable TAP.
If i want to do some job in background for aplication's lifetime, then i must not use TAP either?
I would think of it more as "don't drown the thread pool in work". An exhausted thread pool isn't great for any kind of work.
Should I write a ThradPool implementation with it's own SyncronizationContext to do so?
Is there an other way to run continuation in some set of threads?
You can use SynchronizationContext to control where await resumes executing, but there are still BCL-internal completions that need to queue to the thread pool. There's no controlling that; the only real option is to keep the thread pool free.
I have a method void DoWork(object input) that takes roughly 5 seconds to complete. I have read that Thread is better suited than ThreadPool for these longer operations but I have encountered a problem.
I click a button which calls threadRun.Start(input) which runs and completes fine. I click the button again and receive the following exception:
Thread is running or terminated; it cannot restart.
Can you not "reuse" a Thread? Should I use ThreadPool? Why is Thread "better suited for longer operations" compared to ThreadPool? If you can't reuse a thread, why use it at all (i.e. what advantages does it offer)?
Can you not "reuse" a Thread?
You can. But you have to code the thread not to terminate but to instead wait for more work. That's what a thread pool does.
Should I use ThreadPool?
If you want to re-use a thread, yes.
Why is Thread "better suited for longer operations" compared to ThreadPool?
Imagine a thread pool that is serving a large number of quick operations. You don't want to have too many threads, because the computer can only do so many things at a time. Each long operation you make the thread pool do ties up a thread from the pool. So the pool either has to have lots of extra threads or may run short of threads. Neither leads to an efficient thread pool design.
For longer operations, the overhead of creating and destroying a thread is very small in comparison to the cost of the operation. So the normal downside of using a thread just for the operation doesn't apply.
If you can't reuse a thread, why use it at all (i.e. what advantages does it offer)?
I'm assuming you mean using a thread dedicated to a job that then terminates over using a thread pool. The advantage is that the number of threads will always equal the number of jobs this way. This means you have to create a thread every time you start a job and destroy a thread every time you finish one, but you never have extra threads nor do you ever run short on threads. (This can be a good thing with I/O bound threads but can be a bad thing if most threads are CPU bound most of the time.)
Thread.Start documentation says:
Once the thread terminates, it cannot be restarted with another call
to Start.
Threads are not reusable. I have already faced this problem a while ago, the solution was to create a new Thread instance whenever needed.
It looks like this by by design.
I encountered the same problem and the only solution I could find was to recreate the thread. In my case I wasn't restarting the thread very often so I didn't look any further.
A search now has turned up this thread on social.msdn where the accepted answer states:
a stopped or aborted thread cannot be stated again.
The MSDN repeat this as well:
trying to restart an aborted thread by calling Start on a thread that has terminated throws a ThreadStateException.
As the message states, you cannot restart the thread. You can simply create a new thread for your next operation. Or, you might consider a design where the background thread keeps working until it completes all of your tasks, rather than launch a new thread for each one.
for(;;){} or while(true){} are useful constructs to 'reuse' a thread. Typically, the thread waits on some synchronization object at the top of these loops. In your example, you could wait on an event or semaphore and signal it from your button OnClick() handler.
It's just in background mode. It sounds like you need to use the ThreadPool because re-starting and re-creating Thread objects are very expensive operations. If you have a long running job that may last longer than your main process, then consider the use of a Windows Service.
The Microsoft .NET Base Class Library provides several ways to create a thread and start it. Basically the invocation is very similar to every other one providing the same kind of service: create an object representing an execution flow (or more), assign it a delegate representing the execution flow to execute and, eventually, depending on delegate signature, an object as a parameter.
Well, there are two approaches (essentially):
1) Using the System.Threading.Thread class.
Thread curr = new Thread(myfunction); /* In a class, myfunction is a void taking an object */
curr.Start(new Object()); /* Or something else to be downcast */
2) Using the System.Threading.ThreadPool class.
ThreadPool.QueueUserWorkItem(myfunction, new Object()); /* Same philosophy here */
Are there any special reasons why I should use 1) or 2)?
Performance reasons?
Patterns?
What is the best approach?
I have a feeling that the answer is: "Depend by the situation". Could you please list some situations where one approach is better than another?
Starting a new thread can be a very expensive operation. The thread pool reuses threads and thus amortizes the cost. Unless you need a dedicated thread, the thread pool is the recommended way to go. By using a dedicated thread you have more control over thread specific attributes such as priority, culture and so forth. Also, you should not do long running tasks on the thread pool as it will force the pool to spawn additional threads.
In addition to the options you mention .NET 4 offers some great abstractions for concurrency. Check out the Task and Parallel classes as well as all the new PLINQ methods.
The Managed Thread Pool has some very good guidelines on when NOT to use the thread pool.
In my experience, you want to create your own thread when you need a persistent, dedicated, long-running thread. For everything else, use asynchronous delegates or something like QueueUserWorkItem, BackgroundWorker, or the Task-related features of .NET 4.0.
Threads in ThreadPool are background threads;
All threads created and started by a new Thread object are foreground threads.
A background thread does not keep the managed execution environment running.
refer to http://msdn.microsoft.com/en-us/library/h339syd0.aspx for more.
In .NET 4.5.2 they added a new method: HostingEnvironment.QueueBackgroundWorkItem.
This appears to be an alternative to ThreadPool.QueueUserWorkItem. Both behave similarly, but there are some nice benefits to using the new method when working in ASP.NET:
The HostingEnvironment.QueueBackgroundWorkItem method lets you
schedule small background work items. ASP.NET tracks these items and
prevents IIS from abruptly terminating the worker process until all
background work items have completed. This method can't be called
outside an ASP.NET managed app domain.
Using the ThreadPool, you have less control of the threading system. This is a trade off to simplify the process for you. If you have all that you need from the ThreadPool, you should feel free to utilize it. If you need more control of the threads, then you need to of course use the Thread classes.
ThreadPool.QueueUserWorkItem() is basically for fire-and-forget scenarios, when application doesn't depend on whether operations will finish or not.
Use classic threads for fine-grained control.
You should use ThreadPool.QueueUserWorkItem except in cases of:
You require a foreground thread.
You require a thread to have a particular priority.
You have tasks that cause the thread to block for long periods of
time. The thread pool has a maximum number of threads, so a large
number of blocked thread pool threads might prevent tasks from
starting.
You need to place threads into a single-threaded apartment. All
ThreadPool threads are in the multithreaded apartment.
You need to have a stable identity associated with the thread, or to
dedicate a thread to a task.
Reference link.
In this web tutorial on threading in C#, Joseph Albahari writes: "Don't go sleeping in pooled threads!" Why should you not do this? How badly can it affect performance? (It's not that I want to do it; I'm just curious.)
There are only a limited number of threads in the thread pool; thread pools are designed to efficiently execute a large number of short tasks. They rely on each task finishing quickly, so that the thread can return to the pool and be used for the next task.
So sleeping in a thread pool thread starves out the pool, which may eventually run out of available threads, and be unable to process the tasks you assign to it.
The thread pool is meant to quickly do a relatively short task on a different thread without having to spend the cost of creating a new thread. The thread pool has a maximum number of threads, and once that is reached, tasks are queued until a thread becomes available.
A thread sleeping on the thread pool would therefore hold up the queue, or contribute to thread pool exhaustion.
Thread is a heavy-weight object.
Creating a new thread requires lots of resources, such as assigning 1 MB for a managed stack, creating managed thread object, kernel stack, kernel thread object, user thread environment block. This all takes time and memory. Therefore you do not want to create and destroy objects really quickly. Furthermore, once you have more than one thread context switching will take some resources as well
Thread pool is a place where CLR can put unused threads, in case your application needs it. Threadpool initially contains 0 threads, once you request a thread from a pool, the pool will quickly create the minimum number of threads defined for the pool. After around 2 minutes unused threads get killed. But if the load increases and you need more threads, thread pool will slowly create new threads until the maximum bound reached. You cannot have more threads than maximum, all new requests will be queued and executed once a working thread returned to the pool. In worse case scenario you can get OutOfMemoryException
If a thread taken from a pool is blocked, it:
Holds the resources
Does not do any valuable work, while an application may need this thread for a new request
Breaks scalability by introducing blocks
my Question is :
I am trying to work with multi threading TECHNIC
so I used threadPool but what I want is the following
I want to identify the size of the ThreadPool when the program is launching
when I have Data to manage , I will take a thread from The ThreadPool to work with this Item,
as I have read you can define items in threadPool as you want but each thread will Run Automaticly I want to to have control over the thread to determine when the thread should run
If no Data The thread should wait(or stop) when I have a new Data(it's like a request)
one of the threads will run ..... thanks
When using the ThreadPool you will typically queue a request to the pool with some (optional) input data, which will cause the pool to pick an available thread and run the process. When that is done, the thread is returned to the pool, and will be available for another request. You usually do not need to bother about managing the threads, but can simply queue a work item whenever needed:
DataToWorkWith dataItem = GetDataToWorkWith();
if (dataItem != null)
{
ThreadPool.QueueUserWorkItem(MyProcessingMethod, dataItem);
}
// somewhere else in the class
private void MyProcessingMethod(object dataItem)
{
// work with the dataItem; this will run on a threadpool thread, if
// invoked through the thread pool
}
So, all you would need to do is set up some process figuring out if there is data to work with, queue the requests in the ThreadPool and let it do its job.
Here's a short summary on the C# ThreadPool Usage. Here's the MSDN How To: Use a ThreadPool. And here's the ThreadPool reference.
In particular, you can get the available threads using GetAvailableThreads. You can also control the min and max number of threads in the thread pool by using SetMinThreads and SetMaxThreads.
In general though, I would advise against messing with the numbers of threads, unless you know exactly what you are doing. The thread pool is shared by you and the CLR components, so by changing the number of threads you can affect the CLR behavior. For more details, read the Remarks section in the ThreadPool class documentation.
You don't typically manually manage threads from the ThreadPool. The recommended usage is to queue a delegate as Fredrik exemplified, and let the ThreadPool manage the thread. With this convention, if there is no data, you shouldn't queue any work. When data becomes available, you can queue the work. If you're looking for a way to run a background process, when your application starts, you can create a Timer and add it to the application's state, or you can define a static class that manages a Timer and touch that class on application start.