views:

417

answers:

1

I'm working with a NamedPipeServerStream to communicate between two processes. Here is the code where I initialize and connect the pipe:

void Foo(IHasData objectProvider)
{
    Stream stream = objectProvider.GetData();
    if (stream.Length > 0)
    {
        using (NamedPipeServerStream pipeServer = new NamedPipeServerStream("VisualizerPipe", PipeDirection.Out, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous))
        {
            string currentDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            string uiFileName = Path.Combine(currentDirectory, "VisualizerUIApplication.exe");
            Process.Start(uiFileName);
            if(pipeServer.BeginWaitForConnection(PipeConnected, this).AsyncWaitHandle.WaitOne(5000))
            {
                while (stream.CanRead)
                {
                    pipeServer.WriteByte((byte)stream.ReadByte());
                }
            }
            else
            {
                throw new TimeoutException("Pipe connection to UI process timed out.");
            }
        }
    }
}

private void PipeConnected(IAsyncResult e)
{
}

But it never seems to wait. I constantly get the following exception:

System.InvalidOperationException: Pipe hasn't been connected yet. at System.IO.Pipes.PipeStream.CheckWriteOperations() at System.IO.Pipes.PipeStream.WriteByte(Byte value) at PeachesObjectVisualizer.Visualizer.Show(IDialogVisualizerService windowService, IVisualizerObjectProvider objectProvider)

I would think that after the wait returns everything should be ready to go.

If I use pipeServer.WaitForConnection() everything works fine, but hanging the application if the pipe doesn't connect is not an option.

+2  A: 

You need to call EndWaitForConnection.

var asyncResult = pipeServer.BeginWaitForConnection(PipeConnected, this);

if (asyncResult.AsyncWaitHandle.WaitOne(5000))
{
    pipeServer.EndWaitForConnection(asyncResult);

    // ...
}

See: IAsyncResult design pattern.

dtb
I tried this approach and now it waits for about 10 seconds before connecting, but when I don't use BeginWait it connects instantly. According to MSDN AsyncWaitHandle.WaitOne(5000) blocks until signaled but that is apparently not the case.
Farnk
Sorry, my copy code was wrong and was causing it to hang for a little while. I fixed the code and now this works. Thanks!
Farnk