Reputation: 3875
As a part of a task I'm working now I need to create several Tcp/Ip endpoints. I was surprised to realize that this is so slow. Here is an example of code:
var started = new AutoResetEvent(false);
for (int i = 20000; i < 20050; i++)
{
var watch = Stopwatch.StartNew();
started.Reset();
Task.Run(() =>
{
var listener = new Socket(
AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp
);
listener.Bind(new IPEndPoint(
IPAddress.Parse("127.0.0.1"), i)
);
listener.Listen(1);
started.Set();
var handler = listener.Accept();
// here goes work after socket is opened
// code omitted for brevity
});
started.WaitOne();
watch.Stop();
Console.WriteLine("Openned in ---> {0}",
watch.ElapsedMilliseconds);
}
Here is an example of output.
Openned in ---> 73
Openned in ---> 0
Openned in ---> 0
Openned in ---> 570
Openned in ---> 999
Openned in ---> 1000
Openned in ---> 999
Openned in ---> 998
Openned in ---> 998
Openned in ---> 1000
Openned in ---> 1000
Openned in ---> 998
Openned in ---> 998
Openned in ---> 1000
As a part of the test nobody is expected connect yet, which means it blocks at Accept() line. Who can point me to the reason of why this is happening ?
Upvotes: 0
Views: 118
Reputation: 20140
you have to increase the minimum ThreadPool
By default, the minimum number of threads is set to the number of processors on a system. You can use the SetMinThreads method to increase the minimum number of threads. However, unnecessarily increasing these values can cause performance problems. If too many tasks start at the same time, all of them might appear to be slow. In most cases, the thread pool will perform better with its own algorithm for allocating threads. Reducing the minimum to less than the number of processors can also hurt performance.
example;
static void Main(string[] args)
{
ThreadPool.SetMinThreads(100,100);
var started = new AutoResetEvent(false);
//....
Upvotes: 0
Reputation: 15772
The problem comes from your usage of Task.Run
. It does not do what you think it does. Task.Run
does not create a thread. Instead it runs work on a ThreadPool
. The simplest change to "fix" this is to use Task.Factory.StartNew(..., TaskCreationOptions.LongRunning)
instead.
However it makes much more sense to make usage of async await, unless you are actually working in the HF space, and this is for a trading/real time pricing platform. In which case I really need to stop communicating with you.
Upvotes: 1