ivan.web Home | About | Mailing List | Contact


 » Articles










 


Part 1
» 1. Introduction
» 2. Classes
» 3. Creating a Named Pipe
» 4. Connecting Client Pipes
» 5. Writing and Reading Data
» 6. Other Named Pipes Operations
 
Part 2
» 1. Introduction
» 2. Pipe Connections
» 3. ServerNamedPipe Class
» 4. PipeManager Class
» 5. Client Pipe Connections
 
» .NET Named Pipes Discussion

   

Inter-Process Communication in .NET Using Named Pipes, Part 2

4. PipeManager Class

The PipeManager class is responsible for creating server pipes when necessary, manage the threads and also generate the response to the client requests. Below are displayed and described parts of the code in the PipeManager Class.

The Initialize method creates a new thread, which calls the Start method:

public void Initialize() {
  Pipes = Hashtable.Synchronized(_pipes);
  Mre = new ManualResetEvent(false);
  MainThread = new Thread(new ThreadStart(Start));
  MainThread.IsBackground = true;
  MainThread.Name = "Main Pipe Thread";
  MainThread.Start();
  Thread.Sleep(1000);
}

The PipeManager class creates new pipe connections and threads only on demand. This means that ServerPipeConnection objects are created only when no connections exist or all connection are busy responding to other requests. Normally 2-3 server Named Pipe instances can handle quite a big load of concurrent client requests. This however depends also on the time necessary for processing a client request and generating the response.

References to the created ServerPipeConnection objects are kept in the Pipes Hashtable.

private void Start() {
  try {
    while (_listen) {
      int[] keys = new int[Pipes.Keys.Count];
      Pipes.Keys.CopyTo(keys,0);

Loop through the existing ServerPipeConnection objects and check if they are still functional:

      foreach (int key in keys) {
        ServerNamedPipe serverPipe = (ServerNamedPipe)Pipes[key];
        if (serverPipe != null && 
             DateTime.Now.Subtract(serverPipe.LastAction).Milliseconds >
             PIPE_MAX_STUFFED_TIME && serverPipe.PipeConnection.GetState()
             != InterProcessConnectionState.WaitingForClient) {
          serverPipe.Listen = false;
          serverPipe.PipeThread.Abort();
          RemoveServerChannel(serverPipe.PipeConnection.NativeHandle);
        }
      }

This is determined by checking how long the pipe has been in a state other than "WaitingForClient".

The NumberPipes field contains the maximum number of server Named Pipes we want to have on the server:

      if (numChannels <= NumberPipes) {
        ServerNamedPipe pipe = new ServerNamedPipe(PipeName, OutBuffer, 
           InBuffer, MAX_READ_BYTES);
        try {

The Connect method puts the newly created pipe in listening mode, which blocks the thread until a client attempts to make a connection:

          pipe.Connect();
          pipe.LastAction = DateTime.Now;
          System.Threading.Interlocked.Increment(ref numChannels);

Start the ServerPipeConnection thread:

          pipe.Start();
          Pipes.Add(pipe.PipeConnection.NativeHandle, pipe);
        }
        catch (InterProcessIOException ex) {
          RemoveServerChannel(pipe.PipeConnection.NativeHandle);
          pipe.Dispose();
        }
      }
      else {
        Mre.Reset();
        Mre.WaitOne(1000, false);
      }
    }
  }
  catch {
    // Log exception
  }
}





.NET Named Pipes Discussion

New Thread | View Details


New Thread | View Details

 
© 2009 by Ivan Latunov. Disclaimer.