Остановите прослушиватель TCP с помощью токена отмены задачи - PullRequest
1 голос
/ 21 апреля 2019

Я не могу использовать токены отмены для остановки прослушивателя TCP. Первый фрагмент кода является примером, в котором я могу успешно остановить цикл while в методе из другого класса. Поэтому я не понимаю, почему я не могу применить подобную логику к классу прослушивателей TCP. Много дней потратил на чтение замысловатых ответов по этой теме и не могу найти подходящего решения.

Мое приложение требует, чтобы прослушиватель TCP давал пользователю возможность остановить его на стороне сервера, а не на клиенте. Если пользователь хочет перенастроить номер порта для этого прослушивателя, то в настоящее время ему придется завершить работу программного обеспечения, чтобы Windows закрыла основной сокет, это не очень хорошо, так как это повлияет на другие службы, работающие в моем приложении.

Этот первый фрагмент кода является просто примером, в котором я могу остановить запуск цикла while, все работает нормально, но это не так важно, кроме faat. Я ожидаю, что это сработает для моего прослушивателя TCP:

 public void Cancel(CancellationToken cancelToken) // EXAMPLE WHICH IS WORKING
    {
        Task.Run(async () => 
        {
            while (!cancelToken.IsCancellationRequested)
            {
                await Task.Delay(500);
                log.Info("Test Message!");
            }
        }, cancelToken);
    }

Ниже приведен фактический код прослушивателя TCP, с которым я борюсь

 public void TcpServerIN(string inboundEncodingType, string inboundIpAddress, string inboundLocalPortNumber, CancellationToken cancelToken)
    {
        TcpListener listener = null;

        Task.Run(() =>
        {
            while (!cancelToken.IsCancellationRequested)
            {
                try
                {
                    IPAddress localAddr = IPAddress.Parse(inboundIpAddress);
                    int port = int.Parse(inboundLocalPortNumber);
                    listener = new TcpListener(localAddr, port);
                    // Start listening for client requests.
                    listener.Start();
                    log.Info("TcpListenerIN listener started");

                    // Buffer for reading data
                    Byte[] bytes = new Byte[1024];
                    String data = null;

                    // Enter the listening loop.
                    while (true)
                    {
                        // Perform a blocking call to accept client requests.
                        TcpClient client = listener.AcceptTcpClient();

                        // Once each client has connected, start a new task with included parameters.
                        var task = Task.Run(() =>
                        {
                            // Get a stream object for reading and writing
                            NetworkStream stream = client.GetStream();

                            data = null;
                            int i;

                            // Loop to receive all the data sent by the client.
                            while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
                            {
                                // Select Encoding format set by string inboundEncodingType parameter.
                                if (inboundEncodingType == "UTF8") { data = Encoding.UTF8.GetString(bytes, 0, i); }
                                if (inboundEncodingType == "ASCII") { data = Encoding.ASCII.GetString(bytes, 0, i); }

                                // Use this if you want to echo each message directly back to TCP Client
                                //stream.Write(msg, 0, msg.Length);

                                // If any TCP Clients are connected then pass the appended string through
                                // the rules engine for processing, if not don't send.
                                if ((listConnectedClients != null) && (listConnectedClients.Any()))
                                {
                                    // Pass the appended message string through the SSSCRulesEngine
                                    SendMessageToAllClients(data);
                                }
                            }
                            // When the remote client disconnetcs, close/release the socket on the TCP Server.
                            client.Close();
                        });
                    }
                }
                catch (SocketException ex)
                {
                    log.Error(ex);
                }
                finally
                {
                    // If statement is required to prevent an en exception thrown caused by the user
                    // entering an invalid IP Address or Port number.
                    if (listener != null)
                    {
                        // Stop listening for new clients.
                        listener.Stop();
                    }
                }
            }
            MessageBox.Show("CancellationRequested");
            log.Info("TCP Server IN CancellationRequested");
        }, cancelToken);
    }
...