AcceptTcpClientAsync с задержкой при многократных соединениях - PullRequest
0 голосов
/ 24 апреля 2019

У меня есть сервер и клиент, соединяющийся через TCP-соединение. Если на сервер отправляется несколько одновременных запросов на подключение, сначала быстро создается несколько подключений, а затем клиенты начинают подключаться с интервалом около секунды.

Я обнаружил только зависимость, которая позволяет подключать столько клиентов, сколько имеется процессорных ядер.

Код сервера:

    class Program {
        static void Main(string[] args) {
            var loggerFactory = new LoggerFactory().AddNLog();
            var logger = loggerFactory.CreateLogger<Program>();

            var tcpListener = new TcpListener(IPAddress.Any, 9100);
            tcpListener.Start();

            var sem = new SemaphoreSlim(18, 18);
            while (true) {
                sem.Wait();

                tcpListener
                    .AcceptTcpClientAsync()
                    .ContinueWith(async task => {
                        logger.LogInformation("Client accepted");

                        sem.Release();
                    });
            }
        }
    }

Код клиента:

class Program {
        static void Main(string[] args) {
            var loggerFactory = new LoggerFactory().AddNLog();
            var logger = loggerFactory.CreateLogger<Program>();

            var clientCount = 100;
            for (int i = 0; i < clientCount; i++) {
                Task.Run(() => {
                    var guid = Guid.NewGuid();

                    var client = new TcpClient();
                    client.Connect(IPAddress.Loopback, 9100);

                    logger.LogInformation($"{guid} Connected");

                    Thread.Sleep(1000000);
                });
            }

            while (true) { }
        }
    }

Журнал сервера (Windows10 x64 / 6 core / netcore2.2):

2019/04/24 10:59:50.270|INFO|Test.Server.Tcp.Program|Client accepted 
2019/04/24 10:59:50.295|INFO|Test.Server.Tcp.Program|Client accepted 
2019/04/24 10:59:50.296|INFO|Test.Server.Tcp.Program|Client accepted 
2019/04/24 10:59:50.296|INFO|Test.Server.Tcp.Program|Client accepted 
2019/04/24 10:59:50.297|INFO|Test.Server.Tcp.Program|Client accepted 
2019/04/24 10:59:50.297|INFO|Test.Server.Tcp.Program|Client accepted 
2019/04/24 10:59:51.252|INFO|Test.Server.Tcp.Program|Client accepted 
2019/04/24 10:59:52.252|INFO|Test.Server.Tcp.Program|Client accepted 
2019/04/24 10:59:53.252|INFO|Test.Server.Tcp.Program|Client accepted 
2019/04/24 10:59:54.252|INFO|Test.Server.Tcp.Program|Client accepted 
2019/04/24 10:59:55.252|INFO|Test.Server.Tcp.Program|Client accepted 

Журнал сервера (Kubuntu x64 / 8 core / netcore2.2)

2019/04/24 11:17:42.464|INFO|Test.Server.Tcp.Program|Client accepted 
2019/04/24 11:17:42.464|INFO|Test.Server.Tcp.Program|Client accepted 
2019/04/24 11:17:42.464|INFO|Test.Server.Tcp.Program|Client accepted 
2019/04/24 11:17:42.464|INFO|Test.Server.Tcp.Program|Client accepted 
2019/04/24 11:17:42.464|INFO|Test.Server.Tcp.Program|Client accepted 
2019/04/24 11:17:42.464|INFO|Test.Server.Tcp.Program|Client accepted 
2019/04/24 11:17:42.464|INFO|Test.Server.Tcp.Program|Client accepted 
2019/04/24 11:17:42.464|INFO|Test.Server.Tcp.Program|Client accepted 
2019/04/24 11:17:50.937|INFO|Test.Server.Tcp.Program|Client accepted 
2019/04/24 11:17:59.941|INFO|Test.Server.Tcp.Program|Client accepted 
2019/04/24 11:18:09.943|INFO|Test.Server.Tcp.Program|Client accepted 
2019/04/24 11:18:21.446|INFO|Test.Server.Tcp.Program|Client accepted 
2019/04/24 11:18:33.449|INFO|Test.Server.Tcp.Program|Client accepted

Как я могу ускорить клиентские соединения?

1 Ответ

1 голос
/ 24 апреля 2019

Рабочий код клиента с TaskCreationOptions.LongRunning:

    class Program {
        static void Main(string[] args) {
            var loggerFactory = new LoggerFactory().AddNLog();
            var logger = loggerFactory.CreateLogger<Program>();

            var clientCount = 100;
            for (int i = 0; i < clientCount; i++) {
                var client = new TcpClient();
                client
                    .ConnectAsync(IPAddress.Loopback, 9100)
                    .ContinueWith(async task => {
                        await task;

                        logger.LogInformation("Connected");

                        await Task.Delay(1000000); // a lot of work
                    }, TaskContinuationOptions.LongRunning);
            }

            while (true) { }
        }
    }

...