You are using ThreadPool and want to improve performance and throughput. The SetMinThreads method allows you to alleviate some bottlenecks with ThreadPool. Estimate a good setting for minimum threads.
First we need to see why we need a minimum thread setting. The reason in some cases is that Microsoft has some safeguards in their thread code that interfere.
MSDN on ThreadPool.SetMinThreads: This method tells Windows to keep a specific number of idle threads to anticipate new requests.
MSDN on thread intervals: "The thread pool does not immediately begin creating new idle threads" when there are no existing threads remaining for work items. It does this to avoid excessive allocated memory. [ThreadPool.SetMinThreads Method (System.Threading) - MSDN]
The interval MSDN states that the ThreadPool uses in the .NET runtime on Windows is half a second. In the software world, half a second is a long time.
There are two methods that are most important here. The first is ThreadPool.GetMinThreads, which accepts two out parameters. It is useful to get these values for diagnostics or for changing the actual values. [ThreadPool.GetMinThreads Method (System.Threading) - MSDN]
using System;
using System.Threading;
class Program
{
static void Main()
{
// A
// Get the numbers of minimum threads
int w;
int c;
ThreadPool.GetMinThreads(out w, out c);
// B
// Write the numbers of minimum threads
Console.WriteLine("{0}, {1}",
w,
c);
// C
// Change the numbers of minimum threads
ThreadPool.SetMinThreads(20,
c);
// 2, 2
}
}Part B above will display 2, 2 on a dual core machine, but can display 4 on a quad core computer. Remember that multicore computing is new and changing rapidly, so these are subject to changes.
It is advantageous for you to use the SetMinThreads method in some cases. MSDN states that if your app has "bursts of activity" in which many threads are used at once, SetMinThreads improves performance.
This benchmark runs tests of bursts of activity with 50 work items each time. It changes the minimum thread setting from 2 to 40.
using System;
using System.Threading;
class Program
{
static void Main()
{
// 1
// Loop through number of min threads we use
for (int c = 2; c <= 40; c++)
{
// 2
// Use AutoResetEvent for thread management
AutoResetEvent[] arr = new AutoResetEvent[50];
for (int i = 0; i < arr.Length; ++i)
{
arr[i] = new AutoResetEvent(false);
}
// 3
// Set the number of minimum threads
ThreadPool.SetMinThreads(c, 4);
// 4
// Get current time
long t1 = Environment.TickCount;
// 5
// Enqueue 50 work items that run the code in this delegate function
for (int i = 0; i < arr.Length; i++)
{
ThreadPool.QueueUserWorkItem(delegate(object o)
{
Thread.Sleep(100);
arr[(int)o].Set(); // Signals completion
}, i);
}
// 6
// Wait for all tasks to complete
WaitHandle.WaitAll(arr);
// 7
// Write benchmark results
long t2 = Environment.TickCount;
Console.WriteLine("{0},{1}",
c,
t2 - t1);
}
}
}What I found is that increasing the number of minimum threads improved performance dramatically when it reached 5 and continued improving until 13.
Note that this benchmark is highly dependent on your machine's configuration. If you are reading this in 2015, you will need new benchmarks.
We saw how changing the number of minimum threads in the ThreadPool can improve performance on a dual core machine. This is most useful for programs with bursts of activity involving many threads.
Be careful with SetMinThreads, however, because if you keep too many threads, your program's performance may suffer due to increased memory usage.
The technical details for this article were contributed by Neil Justice. Dot Net Perls thanks him for the contribution of this interesting throughput optimization.
ThreadPool in C# has several optimizations for throughput and asynchronous programming, and you can improve upon the defaults. [C# - ThreadPool and Progress UI - dotnetperls.com]