Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
575 views
in Technique[技术] by (71.8m points)

c# - What is a good way to shutdown Threads blocked on NamedPipeServer#WaitForConnection?

I start my application which spawns a number of Threads, each of which creates a NamedPipeServer (.net 3.5 added managed types for Named Pipe IPC) and waits for clients to connect (Blocks). The code functions as intended.

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);
        ....  

Now I also need a Shutdown method to bring this process down cleanly. I tried the usual bool flag isShutdownRequested trick. But the pipestream stays blocked on the WaitForConnection() call and the thread doesn't die.

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 never returns.

An option that I didnt try but would possibly work is to call Thread.Abort and eat up the exception. But it doesn't feel right.. Any suggestions

Update 2009-12-22
Sorry for not posting this earlier.. This is what I received as a response from Kim Hamilton (BCL team)

The "right" way to do an interruptible WaitForConnection is to call BeginWaitForConnection, handle the new connection in the callback, and close the pipe stream to stop waiting for connections. If the pipe is closed, EndWaitForConnection will throw ObjectDisposedException which the callback thread can catch, clean up any loose ends, and exit cleanly.

We realize this must be a common question, so someone on my team is planning to blog about this soon.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This is cheesy, but it is the only method I have gotten to work. Create a 'fake' client and connect to your named pipe to move past the WaitForConnection. Works every time.

Also, even Thread.Abort() did not fix this issue for me.


_pipeserver.Dispose();
_pipeserver = null;

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...