正确完成服务器';s线程

本文关键字:线程 服务器 | 更新日期: 2023-09-27 18:23:42

我有windows窗体。在构造函数中,服务器线程启动

thServer = new Thread(ServerThread);
thServer.Start();

在服务器线程中有TCP侦听器循环:

 while (true) {
    TcpClient client = server.AcceptTcpClient();
    ...
    }

当我关闭主窗体时,这个线程继续等待TCPClient的请求。我怎样才能停止这种例行公事?非常感谢。

正确完成服务器';s线程

最简单的方法是将线程标记为后台线程,这样当主窗体关闭时,它就无法保持进程运行:

thServer = new Thread(ServerThread);
thServer.IsBackground = true;
thServer.Start();

MSDN:线程IsBackground

public partial class Form1 : Form
{
    Thread theServer = null;
    public Form1()
    {
        InitializeComponent();
        this.FormClosed += new FormClosedEventHandler( Form1_FormClosed );
        theServer = new Thread( ServerThread );
        theServer.IsBackground = true;
        theServer.Start();
    }
    void ServerThread()
    {
        //TODO
    }
    private void Form1_FormClosed( object sender, FormClosedEventArgs e )
    {
        theServer.Interrupt();
        theServer.Join( TimeSpan.FromSeconds( 2 ) );
    }
}

一种方法是添加一个标志,作为while循环的条件。当然,您也可以设置Thread对象的IsBackground属性,但您可能需要执行一些清理代码。

示例:

class Server : IDisposable
{
    private bool running = false;
    private Thread thServer;
    public Server()
    {
        thServer = new Thread(ServerThread);
        thServer.Start();
    }
    public void Dispose()
    {
        running = false;
        // other clean-up code
    }
    private ServerThread()
    {
        running = true;
        while (running)
        {
            // ...
        }
    }
}

用法:

using (Server server = new Server())
{
    // ...
}

下面是这个完全相同问题的解决方案。(查看SimpleServer类)

其想法是停止TcpClient,因此对AcceptTcpClient的调用中止。在调用AcceptTcpClient之后,您可能需要询问套接字是否仍然打开。

生成一个特殊的布尔变量,指示表单即将关闭。在后台线程中检查它的值,当它为true时中断循环。在main表单中,将变量值设置为true并调用thServer.Join()以等待线程完成。然后您可以安全地关闭形式。类似这样的东西:

表单中的关闭处理程序:

abortThread = true;
thServer.Join();

在服务器线程循环中:

while (true)
{
   if (abortThread)
      break;
   TcpClient client = server.AcceptTcpClient();
   ...
}