views:

504

answers:

1

I have an IPC problem. I have created into a windows service a NamedPipeServer:

serverPipe = new NamedPipeServerStream(Constants.PIPE_NAME, PipeDirection.InOut, 1, PipeTransmissionMode.Message, PipeOptions.Asynchronous);
Thread thread = new Thread(new ThreadStart(pipeWork));
thread.Start();

where pipeWork is

private static void pipeWork()
{
    try
    {
        byte[] buffer = new byte[1024];
        while (true)
         {
            if (!serverPipe.IsConnected)
                serverPipe.WaitForConnection();
            int nr = serverPipe.Read(buffer, 0, buffer.Length);
            String str=Encoding.Default.GetString(buffer);

  …
        }
    }
    catch (Exception ex)
    {

    }
}

and into a Windows forms I have the client

clientPipe = new NamedPipeClientStream(".", PhotoServiceClassLibrary.Constants.PIPE_NAME, PipeDirection.InOut,PipeOptions.Asynchronous);
                clientPipe.Connect();
                clientPipe.ReadMode = PipeTransmissionMode.Message;

pipeThread=new Thread(new ThreadStart(pipeWork));
            pipeThread.Start();

where pipeWork is

private void pipeWork()
{
    try
    {
        while (true)
        {
            using (StreamReader sr = new StreamReader(clientPipe))
            {
                string message;

                while ((message = sr.ReadLine()) != null)
                {

                    …

                }
            }
        }
    }
    catch (Exception ex)
    {

    }
}

I want when the service begin an action to disable a ContextMenuStrip from the windows forms, for that the service writes a message into a StreamWriter sw:

        StreamWriter write = null;
        write = new StreamWriter(serverPipe);

        if (serverPipe.IsConnected)
        {
            write.Write(message);
            write.Flush();
        }

The code is correct because I created for testing another windows forms which implements the same things like the windows service and the communication between windows forms pipe server -> windows forms pipe client is working well. The problem is that the windows form - client pipe doesn't receive the message from windows service - server pipe.

I know that WCF can be a better idea but i want to understand why is not working at low-level IPC. Why? I've seen an very strange behavior. My service interact 2 times with the windows forms: 1.My service is designed for downloading some photos. When he begin download he sends a message to the windows forms to announcing him that. 2.When i stop the service he sends a message to windows forms and he stops also. i've just discovered that both messages arrive at windows agent only after the service is stoped. Can someone explain why?

A: 

I hope this isn't your real code. It's good that you've got try/catch blocks around the code of your ThreadStart handlers (otherwise an exception would just quietly delete the thread). However, if you're not logging the exception in the catch block, then it's really just as bad.

You've got a mystery (server doesn't receive message), and you're hiding information (an exception has occurred). If you weren't hiding information, you might have the answer for your mystery (server doesn't receive message because an exception has occurred).

John Saunders
no, isn't my real code. My real code is:try{[...]}catch(exception ex){throw ex;}
and, no, i haven't any error... what shoul i have to do to a windows service communicate with a windows forms through a namedpipe???
If you're just going to throw the exception again, do "throw;" not "throw ex;". Better still, if you're just going to rethrow it, then don't catch it. Best, catch it, and log it.
John Saunders
Also, my suggestion would be to stay away from such low-level mechanisms, and use WCF instead. It supports named pipes, and many other forms of binding, and they support binary serialization, so no overhead of SOAP or XML.
John Saunders