Click here to Skip to main content
15,122,003 members
Articles / Programming Languages / C#
Posted 11 Nov 2012

Tagged as


70 bookmarked

C# Async Named Pipes

Rate me:
Please Sign up or sign in to vote.
4.91/5 (47 votes)
11 Nov 2012CPOL3 min read
How to use named pipes with Async
Image 1


The following tip shows how to implement a Named Piped Client/Server using asynchronous methods for communications between .NET applications.


I created this article because I found it hard to find good examples of Named Pipe Client/Server that use async methods. I found a great article on CodeProject by "Maddog Mike B" but it only worked on .NET 3.5, so I had to come up with a new version for .NET 4.5. Most Named Pipe examples seem to be based on synchronous pipes spliced with threading to create asynchronous Pipes. I don't know if the method I provide is correct but it's what has resulted after hours of scouring the net piecing together scraps of information.


This code was tested with Visual Studio 2012 and .NET 4.5. The project is divided into two winforms based projects, PipeTestClient (sends messages to the server) and PipeTestServer (listens for incoming messages from clients). Both projects have been supplied in zip format.

The AsyncCallback method is called when the method completes. In .NET, events can trigger delegates, but also methods can trigger delegates. The AsyncCallback class allows methods to start an asynchronous function and supply a delegate method to call when the asynchronous function completes.

The state object can be used to pass information between the asynchronous function call and the corresponding AsyncCallback method.

Async Listen Method [Listen Server Class]

The Listen() method is called taking one argument - PipeName, this is assigned to a class level var for use later in a recursive function. The NamedPipeServerStream is created using the PipeOptions.Asynchronous argument (needed for async operation). The passed in PipeName is also used. (Must be the same name as the Client). The Servers asynchronous BeginWaitFoConnection() method is called using AsyncCallback to trigger the WaitForConnectionCallback method, which also receives the state object - in this case the original Pipe. Once into the <span style="FONT-FAMILY: 'Segoe UI', Arial, sans-serif; COLOR: rgb(17,17,17); FONT-SIZE: 14px"></span><code>WaitForConnectionCallback method, the passed state pipe is allocated to a local var and waiting for the connection is ended. A read buffer is created and the message data is read into and converted to a string type. The Original server pipe is then killed and a new one created using the same criteria and the original, the new server pipe begins to wait for another connection using its own method as the AsyncCallback Function (recursion).

// Delegate for passing received message back to caller
public delegate void DelegateMessage(string Reply);

class PipeServer
    public event DelegateMessage PipeMessage;
    string _pipeName;

    public void Listen(string PipeName)
            // Set to class level var so we can re-use in the async callback method
            _pipeName = PipeName;
            // Create the new async pipe 
            NamedPipeServerStream pipeServer = new NamedPipeServerStream(PipeName, 
               PipeDirection.In, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);

            // Wait for a connection
            (new AsyncCallback(WaitForConnectionCallBack), pipeServer);
        catch (Exception oEX)

    private void WaitForConnectionCallBack(IAsyncResult iar)
            // Get the pipe
            NamedPipeServerStream pipeServer = (NamedPipeServerStream)iar.AsyncState;
            // End waiting for the connection

            byte[] buffer = new byte[255];

            // Read the incoming message
            pipeServer.Read(buffer, 0, 255);
            // Convert byte buffer to string
            string stringData = Encoding.UTF8.GetString(buffer, 0, buffer.Length);
            Debug.WriteLine(stringData + Environment.NewLine);

            // Pass message back to calling form

            // Kill original sever and create new wait server
            pipeServer = null;
            pipeServer = new NamedPipeServerStream(_pipeName, PipeDirection.In, 
               1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);

            // Recursively wait for the connection again and again....
               new AsyncCallback(WaitForConnectionCallBack), pipeServer);

Async Send Method [PipeClient Class]

The Send() method is called and takes Send String, Pipe name and connection timeout to the server in milliseconds as arguments. Moving through the code, a NamedPipedClientStream (Pipe) is created using the PipeOptions.Asynchronous argument, this is vital if we are going to succeed in sending an async pipe message. We also use the passed in PipeName (this should be the same name as the server is using). Once created, we try to connect to the server, if the timeout argument is left out and the server does not exist, then the Connect method will sit and wait indefinitely, so it makes sense to use a timeout (in milliseconds). A byte array is then created and the send string/message is converted to it. At this point, assuming a successful connection, the clients asynchronous BeginWrite() method is called using AsyncCallback to trigger the AsyncSend method, which also receives the state object - in this case the original Pipe. Once into the AsyncSend method, the passed state pipe is allocated to a local var and the write is ended.

class PipeClient
    public void Send(string SendStr, string PipeName, int TimeOut = 1000)
            NamedPipeClientStream pipeStream = new NamedPipeClientStream
               (".", PipeName, PipeDirection.Out, PipeOptions.Asynchronous);

            // The connect function will indefinitely wait for the pipe to become available
            // If that is not acceptable specify a maximum waiting time (in ms)
            Debug.WriteLine("[Client] Pipe connection established");

            byte[] _buffer = Encoding.UTF8.GetBytes(SendStr);
            (_buffer, 0, _buffer.Length, new AsyncCallback(AsyncSend), pipeStream);
        catch (TimeoutException oEX)

    private void AsyncSend(IAsyncResult iar)
            // Get the pipe
            NamedPipeClientStream pipeStream = (NamedPipeClientStream)iar.AsyncState;

            // End the write
        catch (Exception oEX)


The Server code also includes event delegates to message back to the calling form - included is a threadsafe method for cross thread communication - please see the code.

Start both the client and server apps, Click Listen on the server App. Then click send as many times as you like on the client app. The messaging is instant and reliable.


  • Version 1.0


If anyone has any tips or tricks for making this cleaner/faster, please let me know.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

United Kingdom United Kingdom
No Biography provided

Comments and Discussions

QuestionMessage Closed Pin
11-Nov-20 14:19
MemberMember 1499050811-Nov-20 14:19 
QuestionMessage Closed Pin
28-Oct-20 8:48
MemberMember 1497781428-Oct-20 8:48 
GeneralMy vote of 5 Pin
@theRouxster2-Jul-20 3:17
Member@theRouxster2-Jul-20 3:17 
QuestionThis only works in forms Pin
Member 1482626118-May-20 14:32
MemberMember 1482626118-May-20 14:32 
QuestionProblem with server opening a file upon receiving a client message to do so Pin
Michael B Pliam23-May-19 17:01
MemberMichael B Pliam23-May-19 17:01 
AnswerRe: Problem with server opening a file upon receiving a client message to do so Pin
Michael B Pliam24-May-19 12:09
MemberMichael B Pliam24-May-19 12:09 
AnswerHappy to modify it for mono under Linux Pin
Mei You Qian19-Jul-17 0:36
professionalMei You Qian19-Jul-17 0:36 
SuggestionAccess denied Or Server unable to get message(s) more than one Pin
Sri Nitish3-Mar-16 22:52
MemberSri Nitish3-Mar-16 22:52 
QuestionBuffer size Pin
Raphael Carubbi29-Feb-16 16:03
MemberRaphael Carubbi29-Feb-16 16:03 
QuestionWhy is It working for the first-time only? Pin
Sri Nitish25-Feb-16 0:43
MemberSri Nitish25-Feb-16 0:43 
GeneralMy vote of 2 Pin
zipwax26-Dec-15 13:55
Memberzipwax26-Dec-15 13:55 
GeneralRe: My vote of 2 Pin
Nemo196616-Mar-16 7:20
MemberNemo196616-Mar-16 7:20 
GeneralWell written Pin
echosteg.com2-Oct-15 21:47
Memberechosteg.com2-Oct-15 21:47 
GeneralMy vote of 5 Pin
kezitor16-Sep-15 17:14
Memberkezitor16-Sep-15 17:14 
GeneralMy vote of 5 Pin
Member 1079835231-Jul-14 0:39
MemberMember 1079835231-Jul-14 0:39 
QuestionSupport for multiple servers Pin
AnalogKid1726-Jun-14 12:48
MemberAnalogKid1726-Jun-14 12:48 
AnswerRe: Support for multiple servers Pin
Mick Conroy26-Mar-15 0:15
MemberMick Conroy26-Mar-15 0:15 
QuestionMake it two ways communication Pin
rezer12-Mar-14 19:42
Memberrezer12-Mar-14 19:42 
AnswerRe: Make it two ways communication Pin
john_172628-Apr-14 10:51
Memberjohn_172628-Apr-14 10:51 
SuggestionMaking a background worker for a web application that uses named pipe to communicate. Pin
3rdey330-Nov-13 22:27
Member3rdey330-Nov-13 22:27 
GeneralMy vote of 5 Pin
ChrDressler28-Sep-13 7:01
MemberChrDressler28-Sep-13 7:01 
GeneralMy vote of 5 Pin
Thierry Bachmann2-Sep-13 6:18
MemberThierry Bachmann2-Sep-13 6:18 
GeneralThanks Pin
Jaime Stuardo - Chile24-Aug-13 17:52
MemberJaime Stuardo - Chile24-Aug-13 17:52 
Thanks for sharing! Smile | :)
GeneralMy vote of 5 Pin
Joezer BH23-Jun-13 0:01
professionalJoezer BH23-Jun-13 0:01 
GeneralMy vote of 5 Pin
JerryShiu29-Apr-13 0:12
MemberJerryShiu29-Apr-13 0:12 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.