我正在创建一个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();
}
}
答案 0 :(得分:5)
在NetworkStream上设置超时(client.ReadTimeout = ...)。一旦读取操作超时,检查主线程是否表示您要停止(通过设置变量或AutoResetEvent)。如果已发出停止信号,请正常退出。如果没有,请再次尝试阅读,直到下一次超时。
设置0.5或1秒的超时应该足够了 - 您将能够及时退出线程,但在CPU上非常容易。
答案 1 :(得分:2)
是否有一个好的模式允许安全关闭线程?
将while循环更改为以下内容:
while (!interrupted){
// Do something
}
// declare interrupted as volatile boolean
volatile bool interrupted;
查看此MSDN example了解详情。 将中断的布尔值设置为true将使线程在检查while条件时退出循环。
是否有一个好的模式允许安全关闭TcpListener和 客户端?
为避免重复,请查看此SO question
关于如何终止ReadLine();
上的阻塞线程的问题,以下listener.Server.Close();
应该执行该作业并从阻塞调用返回。
答案 2 :(得分:1)
也许不是同步调用NetworkStream对象上的Read,而是应该使用BeginRead和EndRead异步执行,并在完成后调用NetworkStream上的Close()。