We help IT Professionals succeed at work.

How do I make this Asyncronous NamedPipe work?

byt3
byt3 asked
on
I've done a few days of research attempting to understand how to use NamedPipes asynchronously in C#, but have not had any luck. There are plenty of examples and references, but I don't seem to be understanding them well enough to know what I'm doing wrong, so I am hoping someone will spell it out for me.

Here is the server side code running as a backgroundworker:
private void startSendPipe(object o, DoWorkEventArgs ea) {
            NamedPipeServerStream sendPipe = new NamedPipeServerStream("ShutdownPipeGet",                                           PipeDirection.Out,
                        1,
                        PipeTransmissionMode.Byte,
                        PipeOptions.Asynchronous); //IPC server sender
            StreamWriter sw;
            IAsyncResult aResult = sendPipe.BeginWaitForConnection(
                delegate(IAsyncResult iar) {
                    try {
                        sw = new StreamWriter(sendPipe);
                        sw.WriteLine(waitTime.ToString());  //send integer converted to string across
                        sendPipe.WaitForPipeDrain();        //wait for client to finish download
                        sw.Close();                         //Close streams when done
                    } catch (IOException ioerr) {
                        Console.WriteLine("Send connection was unexpectedly broken to ShutdownAppGUI.");
                    } catch (Exception err) {
                        Console.WriteLine("Unexpected error on send connection: " + err.Message);
                    }
                },
                null
            );
            //keep worker going until either the info has been sent or background worker cancel is requested.
            while (!ea.Cancel && !aResult.IsCompleted) {
                Thread.Sleep(1000);
            }
            if (!aResult.IsCompleted) { sendPipe.EndWaitForConnection(aResult); }
}

Open in new window

 



Here is the client side code running:
 
NamedPipeClientStream npc = new NamedPipeClientStream(".", "ShutdownPipeGet", PipeDirection.In);    //connect to ShutdownAppCLI(server) to get waitime
            StreamReader sr;
            try {
                npc.Connect();
                sr = new StreamReader(npc);
                String theTime = sr.ReadToEnd();
                sr.Close();
                waitTime = Int32.Parse(theTime); //converting string to integer
                TimeLabel.Text = waitTime.ToString();
            } catch (Exception err) {
                MessageBox.Show("ShutdownAppGUI Error: " + err.Message);
            }

Open in new window


On the server side I get the error: Pipe hasn't been connected yet.
On the client side I get nothing from the stream.

Help?
Comment
Watch Question

Commented:
I figured it out. Turns out I need to stop waiting for connection in the callback function. so the delegate would read like this intead:

private void startSendPipe(object o, DoWorkEventArgs ea) {
            NamedPipeServerStream sendPipe = new NamedPipeServerStream("ShutdownPipeGet",                                           PipeDirection.Out,
                        1,
                        PipeTransmissionMode.Byte,
                        PipeOptions.Asynchronous); //IPC server sender
            StreamWriter sw;
            IAsyncResult aResult = sendPipe.BeginWaitForConnection(
                delegate(IAsyncResult iar) {
                    sendPipe.EndWaitForConnection(iar); //***Add this here
                    try {
                        sw = new StreamWriter(sendPipe);
                        sw.WriteLine(waitTime.ToString());  //send integer converted to string across
                        sendPipe.WaitForPipeDrain();        //wait for client to finish download
                        sw.Close();                         //Close streams when done
                    } catch (IOException ioerr) {
                        Console.WriteLine("Send connection was unexpectedly broken to ShutdownAppGUI.");
                    } catch (Exception err) {
                        Console.WriteLine("Unexpected error on send connection: " + err.Message);
                    }
                },
                null
            );
            //keep worker going until either the info has been sent or background worker cancel is requested.
            while (!ea.Cancel && !aResult.IsCompleted) {
                Thread.Sleep(1000);
            }
            if (!aResult.IsCompleted) { sendPipe.EndWaitForConnection(aResult); }
}

Open in new window