ThreadPool not starting new Thread instantly
The ThreadPool
is specifically not intended for long-running items (more specifically, you aren't even necessarily starting up new threads when you use the ThreadPool
, as its purpose is to spread the tasks over a limited number of threads).
If your task is long running, you should either break it up into logical sections that are put on the ThreadPool
(or use the new Task
framework), or spin up your own Thread
object.
As to why you're experiencing the delay, the MSDN Documentation for the ThreadPool
class says the following:
As part of its thread management strategy, the thread pool delays before creating threads. Therefore, when a number of tasks are queued in a short period of time, there can be a significant delay before all the tasks are started.
You only know that the ThreadPool
hasn't reached its maximum thread count, not how many threads (if any) it actually has sitting idle.
why my threadpool 's threads do not finish at same time
The threads are not being started at the same time in your example. Add the following call right after SetMaxThreads
ThreadPool.SetMinThreads(200, 200);
This will make threads start simultaneously. It's something about ThreadPool threads creating mechanics. I recommend to read ThreadPool documentation for details.
To debug it more properly, update your ThreadWhichWillCallSQL_test method to add start time too:
static void ThreadWhichWillCallSQL_test(object o1)
{
Console.WriteLine("start:" + DateTime.Now);
Thread.Sleep(5000);
Console.WriteLine("finish: " + DateTime.Now);
}
Doesn't ThreadPoolExecutor start a new thread before the last thread is finished
You don't tell the executor to run the method, you're executing yourself.
executor.submit(t.run("gg"))
This will evaluate t.run("gg")
- i.e execute the function, before it is even submitted.
You need to tell the executor what to execute, but not execute it:
executor.submit(t.run, ("gg",))
Here I'm telling it to do t.run
with the arguments ("gg",)
Which results in:
start the id: 0
Task Executed <Thread(ThreadPoolExecutor-0_0, started 123145503694848)>
0 -> ('gg',)
start the id: 1
Task Executed <Thread(ThreadPoolExecutor-0_1, started 123145520484352)>
1 -> ('gg',)
...
Force ThreadPool to start the thread sooner
First off, QueueUserWorkItem
doesn't create a thread, it merely places a "task" in the ThreadPool's queue for the workers to pick up and execute. In case of saturation (more tasks than available threads), there is no guarantee of when a worker will become available to execute the task. If you want immediate execution use an instance of Thread
instead. The only way to improve your odds with the ThreadPool is to increase the number of workers.
Edit: Just to be clear, if thread pool threads are indeed free, they will pick up work and execute it usually faster than starting a fresh thread.
Fixed Thread Pool is exiting immediately, not processing threads
exec.shutdown()
doesn't block main thread. If you need to wait for all submitted tasks to finish you need to call exec.awaitTermination(1, TimeUnit.HOUR);
(of course with timeout that makes sense for your application) after call to exec.shutdown();
.
/**
* Blocks until all tasks have completed execution after a shutdown
* request, or the timeout occurs, or the current thread is
* interrupted, whichever happens first.
*/
boolean awaitTermination(long timeout, TimeUnit unit)
throws InterruptedException;
Run a new thread immediately
The simplest way is to just instantiate a Thread
Thread task = new Thread(()=>
{
try
{
ConnectToCodeManager();
string connectionString = ConfigurationManager.ConnectionStrings["DataBaseConnection"].ConnectionString;
SQLTrazabilidadStorage storage = new SQLTrazabilidadStorage(connectionString);
storage.SendAggregation(parentCode, codesManagerURL);
}
catch (Exception ex)
{
log.Error(string.Format("SendAggregation to TrzCodesManagerWS: {0}", ex.ToString()));
}
});
task.Start();
Does Task.Run(Action) Start a new Thread id there are no more threads in the ThreadPool?
would Task.Run start a new Thread if there are none available in the ThreadPool?
Not immediately. The Task would be queued.
But the ThreadPool does manage its threads: when the queue fills up it will create new worker threads at a rate of 2 per second.
And when the queue runs empty Threads will be destroyed at the same rate.
The actual algorithm is a little more involved (from .NET 4 on) but it does mean that the Pool does exercise some relatively simple resource management.
Why does thread pool takes tasks independenty and not concurrently?
Why not concurrently? Why not just time-slice those 10 tasks?
You can have a thread pool that is able to perform ten concurrent tasks. You just need to configure it to have at least ten worker threads. "Time-slicing" tasks is what threads do. What thread pools do is:
- Allow your program to control the number of threads that it uses to perform "background" tasks, and
- Allow your program to re-use threads, which can be much more efficient than creating a new thread for each new task, and then destroying the thread when the task is complete.
Related Topics
How to Have a Loop in a Windows Service Without Using the Timer
How to Split an Ienumerable<String> into Groups of Ienumerable<String>
C# Getting Value of Params Using Reflection
Giving Application Elevated Uac
Cannot Convert Type 'Task<Derived>' to 'Task<Interface>'
Sorting an Array of Folder Names Like Windows Explorer (Numerically and Alphabetically) - Vb.Net
How Should You Diagnose the Error Sehexception - External Component Has Thrown an Exception
Anyone Know of a Set of C# Bindings for Ffmpeg
Reading from Excel (Range into Multidimensional Array) C#
Vertical Text in Wpf Textblock
Getting the Index of a Particular Item in Array
Frombluetoothaddressasync Iasyncoperation Does Not Contain a Definition for 'Getawaiter' Error
Synchronize Scroll Position of Two Richtextboxes
Where Are the Controllercontext and Viewengines Properties in MVC 6 Controller