【问题标题】:Closing threads关闭线程
【发布时间】:2010-12-29 17:22:44
【问题描述】:

我正在用 C# 编写一个 tcp 服务器应用程序。我设计了一个名为 TcpCommunication 的类来实现服务器。 TcpCommunication 拥有下一个成员:

private TcpListener tcpListener;
private TcpClient clientObj;
private Thread listenThread;

还有一个 connect() 方法:

public bool Connect()
{
...
listenThread = new Thread(new ThreadStart(ListenForClients));
        listenThread.IsBackground = true;
        listenThread.Start();
...
}

ListenForClients 方法实现如下:

private void ListenForClients()
    {
        while (true)
        {
            try
            {
                //blocks until a client connects to the server
                clientObj = tcpListener.AcceptTcpClient();

                //create a thread to handle communication with connected client
                Thread clientThread = new Thread(new ThreadStart(Receive));
                clientThread.IsBackground = true;
                clientThread.Start();
             }
             ...
        }
    }

在某些情况下(当用户决定时)我想停止监听新客户端并停止为现有客户端提供服务。 我的问题是:当它们的创建者线程(不是主线程)中止时,所有子线程都会中止吗? 我是否需要保存所有线程的集合并一个一个中止它们,或者下一个实现是否足够?

public bool Disconnect()
    {
        if (listenThread != null)
        {
            listenThread.Abort();
            listenThread.Join();
        }
        tcpListener.Stop();
        return true;
    }

【问题讨论】:

    标签: c# multithreading tcplistener


    【解决方案1】:

    您需要考虑使用本身提供多线程支持的异步套接字。因此,您不需要管理线程。看这个例子:

    http://msdn.microsoft.com/en-us/library/5w7b7x5f.aspx

    【讨论】:

      【解决方案2】:

      线程没有任何关系,你可以按任意顺序杀死它们。你应该持有你创建的线程列表,我不会那么勇敢地杀死应用程序中的所有线程,框架也可能会创建一些。如果我是你,我会在一个循环中中止所有这些,然后在第二个循环中加入所有这些,以使其更快。

      【讨论】:

        【解决方案3】:

        如果您处于阻塞模式,则底层服务器套接字会阻塞线程,因为它是同步 WIN32 操作。

        你不需要一个线程:

        public static void StartTcpListener(TcpListener listener)
        {
            try
            {
                listener.Server.Blocking = false;
                listener.BeginAcceptTcpClient(
                    ar =>
                    {
                        TcpClient client = listener.EndAcceptTcpClient(ar);
                    },
                    listener);
            }
            catch
            {
                // catch exceptions on close, e.g.
            }
        }
        

        如果您在侦听时关闭该套接字,它会在大多数情况下抛出异常,因为在该示例中上下文被 try-catch 块包围。

        【讨论】:

          【解决方案4】:

          当它们的创建者线程(不是主线程)中止时,是否所有子线程都会中止?

          ,即使所有者线程退出,它们也可以运行。线程 B 是在线程 A 中创建和启动的,并不意味着线程 B 是线程 A 的一部分。

          我是否需要保存所有线程的集合并一个一个中止它们,或者下一个实现是否足够?

          根据您的问题,我认为您需要这样做。 (如果我的理解是正确的)在服务器端你只有一个线程ListenForClients,其中几个clientThread 将被创建,因为许多客户端将连接到你的服务器。但是在您的Disconnect 方法中,只有listenThread 被中止,这意味着可能有很多clientThread 仍在运行。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2019-10-27
            • 2011-10-26
            • 1970-01-01
            • 2020-01-27
            • 2011-04-28
            • 1970-01-01
            相关资源
            最近更新 更多