正确的方法来中止被阻止的线程

Nea*_*eal 5 .net c# multithreading design-patterns

我正在创建一个TCP连接的服务器.TCP连接在其自己的线程中运行无限长的时间.是否有一个好的模式允许安全关闭TcpListener和客户端以及线程?以下是我到目前为止的情况.

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

zmb*_*mbq 5

在NetworkStream上设置超时(client.ReadTimeout = ...).一旦读取操作超时,检查主线程是否表示您要停止(通过设置变量或AutoResetEvent).如果已发出停止信号,请正常退出.如果没有,请再次尝试读取,直到下一次超时.

设置0.5或1秒的超时应该足够了 - 您将能够及时退出线程,并且在CPU上非常容易.


GET*_*Tah 2

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

将 while 循环更改为以下内容:

while (!interrupted){
   // Do something
}
// declare interrupted as volatile boolean
volatile bool interrupted;
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请查看此MSDN 示例。将 Interrupted 布尔值设置为 true 将使线程在检查 while 条件时跳出循环。

是否有一个好的模式可以安全关闭 TcpListener 和客户端?

为了避免重复,请检查这个SO问题

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

  • 使用 Server.Close() 是正确的答案。任何阻塞方法都会以 ObjectDisposeException 结束。 (3认同)