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

时间:2015-08-06 00:42:30

标签: c# .net sockets tcp-ip tcpserver

作为我正在工作的任务的一部分,我需要创建几个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()行阻塞。谁能指出我为什么会这样做的原因?

2 个答案:

答案 0 :(得分:1)

问题来自您使用Task.Run。它没有做你认为它做的事情。 Task.Run不会创建线程。相反,它在ThreadPool上运行。最简单的改变是&#34;修复&#34;这是使用Task.Factory.StartNew(..., TaskCreationOptions.LongRunning)代替。

然而,除非你实际上在HF空间工作,否则使用异步等待更有意义,这适用于交易/实时定价平台。在这种情况下,我真的需要停止与你沟通。

答案 1 :(得分:0)

你必须增加最低ThreadPool

  

默认情况下,最小线程数设置为   系统上的处理器。您可以使用SetMinThreads方法   增加最小线程数。然而,不必要的   增加这些值可能会导致性能问题。如果太多了   任务从同一时间开始,所有这些任务似乎都很慢。在   在大多数情况下,线程池将使用自己的算法执行得更好   用于分配线程。将最小值减少到小于数量   处理器也会损害性能。

示例;

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

        var started = new AutoResetEvent(false);

        //....
相关问题