我启动了我的应用程序,它生成了许多Threads,每个Threads创建一个NamedPipeServer(.net 3.5为Named Pipe IPC添加了托管类型)并等待客户端连接(Blocks).代码按预期运行.
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技巧.但是管道流在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!"); } }
加入永不回归.
我没有尝试但可能会工作的选项是调用Thread.Abort并吃掉异常.但它感觉不对..任何建议
更新2009-12-22
很抱歉没有提前发布..这是我收到的Kim Hamilton(BCL团队)的回复
执行可中断WaitForConnection的"正确"方法是调用BeginWaitForConnection,处理回调中的新连接,并关闭管道流以停止等待连接.如果管道关闭,EndWaitForConnection将抛出ObjectDisposedException,回调线程可以捕获它,清除任何松散的端点,并干净地退出.
我们意识到这必须是一个常见问题,因此我的团队中的某个人计划很快就此发表博客.
JasonRShaver.. 38
这很俗气,但这是我开始工作的唯一方法.创建一个'假'客户端并连接到您的命名管道以移过WaitForConnection.每次都有效.
此外,甚至Thread.Abort()也没有为我解决这个问题.
_pipeserver.Dispose(); _pipeserver = null; using (NamedPipeClientStream npcs = new NamedPipeClientStream("pipename")) { npcs.Connect(100); }
Richard.. 14
切换到异步版本:BeginWaitForConnection
.
如果它确实完成了,你需要一个标志,这样完成处理程序就可以调用EndWaitForConnection
吸收任何异常并退出(调用End ...以确保能够清除任何资源).
这很俗气,但这是我开始工作的唯一方法.创建一个'假'客户端并连接到您的命名管道以移过WaitForConnection.每次都有效.
此外,甚至Thread.Abort()也没有为我解决这个问题.
_pipeserver.Dispose(); _pipeserver = null; using (NamedPipeClientStream npcs = new NamedPipeClientStream("pipename")) { npcs.Connect(100); }
切换到异步版本:BeginWaitForConnection
.
如果它确实完成了,你需要一个标志,这样完成处理程序就可以调用EndWaitForConnection
吸收任何异常并退出(调用End ...以确保能够清除任何资源).
您可以使用以下扩展方法.请注意包含'ManualResetEvent cancelEvent' - 您可以从另一个线程设置此事件,以表示等待连接方法现在应该中止并关闭管道.设置m_bShutdownRequested时包含cancelEvent.Set(),关闭应该相对优雅.
public static void WaitForConnectionEx(this NamedPipeServerStream stream, ManualResetEvent cancelEvent) { Exception e = null; AutoResetEvent connectEvent = new AutoResetEvent(false); stream.BeginWaitForConnection(ar => { try { stream.EndWaitForConnection(ar); } catch (Exception er) { e = er; } connectEvent.Set(); }, null); if (WaitHandle.WaitAny(new WaitHandle[] { connectEvent, cancelEvent }) == 1) stream.Close(); if (e != null) throw e; // rethrow exception }