中止阻塞线程的正确方法

本文关键字:方法 线程 | 更新日期: 2023-09-27 18:16:04

我正在创建一个TCP连接的服务器。TCP连接在它自己的线程中运行一段不确定的时间。是否有一个好的模式允许安全关闭TcpListener和Client以及线程?下面是我到目前为止写的。

private volatile bool Shudown;
void ThreadStart1()
{
    TcpListener listener = null;
    TcpClient client = null;
    Stream s = null;
    try
    {
        listener = new TcpListener(60000);
        client = listener.AcceptTcpClient();
        Stream s = client.GetStrea();
        while(!Shutdown)  // use shutdown to gracefully shutdown thread.
        {
            try
            {
                string msg = s.ReadLine();  // This blocks the thread so setting shutdown = true will never occur unless a client sends a message.
                DoSomething(msg);
            }
            catch(IOException ex){ } // I would like to avoid using Exceptions for flow control
            catch(Exception ex) { throw; }
        }
    }
    catch(Exception ex)
    {
        LogException(ex);
        throw ex;
    }
    finally
    {
        if(listener != null) listener.Close();
        if(s != null) s.Close();
        if(client != null) client.Close();
    }
}

中止阻塞线程的正确方法

设置NetworkStream的超时时间(client.ReadTimeout=…)。一旦读取操作超时,检查主线程是否向您发出停止信号(通过设置一个变量或AutoResetEvent)。如果发出停止信号,优雅地退出。如果没有,请重试,直到下一次超时。

设置0.5秒或1秒的超时应该足够了——您将能够及时退出线程,并且对CPU来说非常容易。

是否有一个好的模式允许安全关闭线程?

将while循环修改为:

while (!interrupted){
   // Do something
}
// declare interrupted as volatile boolean
volatile bool interrupted;

查看此MSDN示例了解详细信息。将中断布尔值设置为true将使线程在检查while条件时退出循环。

是否有一个好的模式允许安全关闭TcpListener和客户端吗?

为避免重复,请在SO问题

上打勾。

关于如何在ReadLine();上终止阻塞线程的问题,下面的listener.Server.Close();应该完成这项工作并从阻塞调用返回。

也许不是在NetworkStream对象上同步调用Read,你应该使用BeginRead和EndRead来异步执行,并在完成后在NetworkStream上调用Close()。