我启动应用程序,它生成许多线程,每个线程创建一个命名管道服务器(.Net 3.5添加了命名管道IPC的托管类型),并等待客户端连接(阻塞)。该代码按预期运行。
private void StartNamedPipeServer()
{
using (NamedPipeServerStream pipeStream =
new NamedPipeServerStream(m_sPipeName, PipeDirection.InOut, m_iMaxInstancesToCreate, PipeTransmissionMode.Message, PipeOptions.None))
{
m_pipeServers.Add(pipeStream);
while (!m_bShutdownRequested)
{
pipeStream.WaitForConnection();
Console.WriteLine("Client connection received by {0}", Thread.CurrentThread.Name);
....
现在我还需要一个Shutdown方法来清理这个进程。我尝试了通常的bool标志isShutdownRequested技巧。但是pipestream仍然在WaitForConnection()调用上阻塞,线程不会死亡。
public void Stop()
{
m_bShutdownRequested = true;
for (int i = 0; i < m_iMaxInstancesToCreate; i++)
{
Thread t = m_serverThreads[i];
NamedPipeServerStream pipeStream = m_pipeServers[i];
if (pipeStream != null)
{
if (pipeStream.IsConnected)
pipeStream.Disconnect();
pipeStream.Close();
pipeStream.Dispose();
}
Console.Write("Shutting down {0} ...", t.Name);
t.Join();
Console.WriteLine(" done!");
}
}
Join方法不会返回。
一个我没有尝试但可能可行的选项是调用Thread.Abort并消耗异常。 但这感觉不对... 有什么建议吗?
更新2009-12-22
很抱歉没有早些发布此内容... 这是我从Kim Hamilton(BCL团队)收到的回复:
实现可中断的WaitForConnection的“正确”方法是调用BeginWaitForConnection,在回调中处理新连接,并关闭管道流以停止等待连接。 如果管道已关闭,则EndWaitForConnection将引发ObjectDisposedException,回调线程可以捕获它,清理任何松散的端口,并干净地退出。
我们意识到这必须是一个常见的问题,因此我的团队中的某个人计划很快发布博客文章。