为什么 Socket Accept 需要大约 1 秒才能完成?

Why is Socket Accept taking approx 1 sec to complete?

作为我现在工作的任务的一部分,我需要创建几个 Tcp/Ip 端点。我很惊讶地意识到这太慢了。这是一个代码示例:

        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);
        }

这是一个输出示例。

    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

作为测试的一部分,预计还没有人连接,这意味着它会在 Accept() 行阻塞。谁能指出发生这种情况的原因?

问题出在您对 Task.Run 的使用上。它不做你认为它做的事。 Task.Run 不创建线程。相反,它在 ThreadPool 上运行。对 "fix" 最简单的更改是使用 Task.Factory.StartNew(..., TaskCreationOptions.LongRunning)

然而,使用 async await 更有意义,除非您实际上在 HF space 中工作,这是针对 trading/real 时间定价平台的。那样的话我真的要跟你断绝联系了

你必须增加最小值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.

示例;

    static void Main(string[] args)
    {
        ThreadPool.SetMinThreads(100,100);

        var started = new AutoResetEvent(false);

        //....