views:

599

answers:

3

I am creating a windows service that starts a number of slave processes. In each of these slave process I start listening on a named pipe for message from the master process.

I currently have the situation where the master process calls a slave via a named pipe before the slave is fully started and starts listening on the named pipe.

    ProcessStartInfo processStartInfo = new ProcessStartInfo("slave");
    processStartInfo.Arguments = Address 

    Process process = new Process();
    process.StartInfo = processStartInfo;

    process.Start();

    base.Endpoint.Binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None);
    base.Endpoint.Address = Address;

    base.Channel.RemoteMethod();

If I do this the channel gets into CommunicationState.Faulted and any subsequent calls on the channel fail as well.

What can I do to verify from the master that the slave process starts listening? Or how can I recover from the CommunicationState.Faulted to retry my remote call?

+1  A: 

The only way to recover from the Faulted state is to reiniailize the WCF Client by re-building the instance and call the Open() method.

In general, before I call the service, I always check the Status property and if it is not Opened I try to reinitialize it as I described above. If it fails, there is a problem with the server. (In my case, the state gets faulted due to inactivity, so initialization ussually succedes)

AlexDrenea
How would you actually do the re-build of the instance? Do you create a new instance of the object?
Jeroen Huinink
yes .
AlexDrenea
It took some reshufling of responsibilities between objects, but I have it up and running now. Thanks
Jeroen Huinink
A: 

You can attach to the "ServiceFaulted" event on the host, and use this to perform error handling. According to the documentation, the correct action is to abort the host. You then can try and reinitialise it but it may be an exercise in futility if the system is down.

Spence
The problem is not in the host. The host gets up-and-running. The problem is in the client.
Jeroen Huinink
A: 

Perhaps you could implement a "session" based service. So the client opens the WCF channel and makes a call to open the session (eg. an "open" call). This would let your host know that the slave is listening.

You might want to investigate the callback mechanism of WCF so that the remote communication to the slave is provided via a callback from the "open" call made by it once it has initialised.

Alex Drenea is correct in saying that you want to create a new instance. I would recommend having a look at the ChannelFactory class in WCF for creating the proxies. You can use this with some try catch type behaviour to deal with the initial startup of your slave. You may also want to place a System.Diagnostics.Debugger.Break() in your slave process startup code as the debugger may not attach so you don't see the exception in your slave process.

Can I ask whether you really need process isolation or would using synchronisation and threads be sufficient for your task?

Spence
The slave processes run instances of a third party application with some odd behaviour that we do not want in our main process. We have currently implemented it with threads and are moving it to seperate processes.
Jeroen Huinink
Good. I've met a few unix programmers who just have this urge to make processes in windows and it's the wrong way to go in most cases. Any luck with the named pipe issue?
Spence