当前位置:  开发笔记 > 编程语言 > 正文

关闭在NamedPipeServer#WaitForConnection上阻塞的线程的好方法是什么?

如何解决《关闭在NamedPipeServer#WaitForConnection上阻塞的线程的好方法是什么?》经验,为你挑选了3个好方法。

我启动了我的应用程序,它生成了许多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 ...以确保能够清除任何资源).



1> JasonRShaver..:

这很俗气,但这是我开始工作的唯一方法.创建一个'假'客户端并连接到您的命名管道以移过WaitForConnection.每次都有效.

此外,甚至Thread.Abort()也没有为我解决这个问题.


_pipeserver.Dispose();
_pipeserver = null;

using (NamedPipeClientStream npcs = new NamedPipeClientStream("pipename")) 
{
    npcs.Connect(100);
}



2> Richard..:

切换到异步版本:BeginWaitForConnection.

如果它确实完成了,你需要一个标志,这样完成处理程序就可以调用EndWaitForConnection吸收任何异常并退出(调用End ...以确保能够清除任何资源).



3> 小智..:

您可以使用以下扩展方法.请注意包含'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
    }

推荐阅读
手机用户2402851155
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有