我正在用 C# 构建一个 Windows tcp 客户端服务,该服务侦听远程 tcp 服务器,该服务器在发生事件时发送状态消息。此外,我可以通过向服务器发送请求-回复消息来验证连接。现在我像这样在 OnStart()
方法中旋转主线程:
protected override void OnStart(string[] args)
{
_worker = new Thread(DoWork);
_worker.Start();
}
在DoWork
内,我定义了新线程check_conn
private void DoWork()
{
try
{
....
client = new TcpClient();
try
{
using (NetworkStream stream = client.GetStream())
{
check_conn = new Thread(CheckConnection);
check_conn.Start();
...
}
}
...
}
...
}
在我的 check_conn
线程中,我基本上向服务器发送周期请求消息并收到回复。
private void CheckConnection()
{
using (NetworkStream stream = client.GetStream())
{
while (!_shutdownEvent.WaitOne(0))
{
byte[] notify = Encoding.ASCII.GetBytes("Are you alive");
stream.Write(notify, 0, notify.Length);
Thread.Sleep(1 * 60 * 1000);
}
}
}
我运行这项服务有一段时间了,它似乎运行良好。我担心的是,这是正确的做法吗?我的意思是有没有比我在这里实现的方式(在线程中有一个线程)更好的方法来检查连接?我应该为两个线程使用一个 NetworkStream
还是可以像我一样使用它?
此外,我在停止服务时遇到了一些挑战。我有 stream.Read()
方法可以从服务器读取状态更新。这是一个阻塞调用。为了打破这一点,在我的 onStop()
方法中,我 close()
client
并设置 ManualResetEvent _shutdownEvent
并等待线程 _worker
通过调用 {{1} } 方法就可以了。问题是,如果我没有在 Join()
方法上指定时间跨度,服务状态会在停止时卡住并且永远不会停止。如果我指定时间跨度,它会停止:
Join()
这是预期的行为吗?