我的窗口上有两个Button连接了两个ICommands

public ICommand Start { get; set; }
public ICommand Stop { get; set; }


像这样在Constructor中初始化的:

Start = new Command(StartServer, (o) => !IsListening);
Stop = new Command(StopServer, (o) => IsListening);


并执行以下操作:

async void StartServer(object obj)
{
    server.Start();
    IsListening = true;
    Status = "Listening";
    try
    {
        while (IsListening)
        {
            var cw = new ClientWrapper();
            cw.Client = await server.AcceptTcpClientAsync();
            cw.EndPoint = cw.Client.Client.RemoteEndPoint;
            Pool.Add(cw);
            HandleClient(cw);
        }
    }
    catch (Exception e)
    {
        throw;
    }
}


void StopServer(object obj)
{
    DisposeClients();
    server.Stop();
    IsListening = false;
    Status = "Start Server";
}


当我单击Start时,它开始侦听并接受客户端,没有任何问题。没有任何客户端,如果我只是Start服务器,然后单击Stop,它将正常执行StopServer函数,然后点击ICommandExecute函数,并进入catch方法的StartServer块!并且e中的消息是:


  无法访问已处置的对象。对象名称:
  'System.Net.Sockets.Socket'。


我不希望它进入catch块!如何正确处理?

最佳答案

using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace tcplistenertest
{
    class Program
    {
        static void Main(string[] args)
        {
            Thread listenerThread = StartBackgroundThread(new ThreadStart(ThreadProc));

            while(Console.ReadLine() != string.Empty)
            {
            }

            mListener.Stop();
            listenerThread.Join();
        }

        static void ThreadProc()
        {
            try
            {
                mListener = StartListening();

                AcceptLoop(mListener);
            }
            catch(Exception e)
            {
                Console.WriteLine($"ThreadProc error: {e.Message}");
                Console.WriteLine($"Stack trace:{Environment.NewLine}{e.StackTrace}");
            }
        }

        static Thread StartBackgroundThread(ThreadStart task)
        {
            Thread thread = new Thread(task);
            thread.IsBackground = true;
            thread.Start();
            return thread;
        }

        static TcpListener StartListening()
        {
            TcpListener result = new TcpListener(IPAddress.Any, PORT);
            result.Start();

            return result;
        }

        static void AcceptLoop(TcpListener listener)
        {
            // this is the main loop of the Socket based server
            while (true)
            {
                Socket socket = null;
                try
                {
                    Console.WriteLine("Accepting connection...");
                    socket = AcceptConnection(listener);
                    Console.WriteLine($"Connection accepted from {socket.RemoteEndPoint}");
                }
                catch (SocketException e)
                {
                    Console.WriteLine($"Socket error accepting connection: {e.Message}");
                    Console.WriteLine($"Stack trace:{Environment.NewLine}{e.StackTrace}");
                    break;
                }
                catch (Exception e)
                {
                    Console.WriteLine($"Generic error accepting connection: {e.Message}");
                    Console.WriteLine($"Stack trace:{Environment.NewLine}{e.StackTrace}");
                    break;
                }

                try
                {
                    socket.Close();
                }
                catch (Exception e)
                {
                    Console.WriteLine($"Error closing socket: {e.Message}");
                    Console.WriteLine($"Stack trace:{Environment.NewLine}{e.StackTrace}");
                    break;
                }
            }

            Console.WriteLine("Accept loop thread stopping");
        }

        static Socket AcceptConnection(TcpListener listener)
        {
            Socket socket = listener.AcceptSocket();
            try
            {
                socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.Debug, 1);
                LingerOption optionValue = new LingerOption(true, 3);

                socket.SetSocketOption(SocketOptionLevel.Socket,
                    SocketOptionName.Linger, optionValue);

                return socket;
            }
            catch (Exception)
            {
                socket.Close();
                throw;
            }
        }

        static TcpListener mListener;
        const int PORT = 55000;
    }
}

关于c# - 如何正确停止异步TcpListener?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58517207/

10-09 18:01