ruslander
ruslander

Reputation: 3875

Why is Socket Accept taking approx 1 sec to complete?

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

Answers (2)

Fredou
Fredou

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

Aron
Aron

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

Related Questions