Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to determine that a WCF Service is ready?

Tags:

c#

wcf

I have the following scenario:

My main Application (APP1) starts a Process (SERVER1). SERVER1 hosts a WCF service via named pipe. I want to connect to this service (from APP1), but sometimes it is not yet ready.

I create the ChannelFactory, open it and let it generate a client. If I now call a method on the generated Client I receive an excpetion whitch tells me that the Enpoint was not found:

var factory = new ChannelFactory<T>(new NetNamedPipeBinding(), new EndpointAddress("net.pipe//localhost/myservice");
factory.Open()

var Client = factory.CreateChannel();
Client.Foo();

If I wait a little bit before calling the service, everything is fine;

var Client = factory.CreateChannel();
Thread.Sleep(2000);
Client.Foo();

How can I ensure, that the Service is ready without having to wait a random amount of time?

like image 849
Jaster Avatar asked Mar 22 '11 13:03

Jaster


Video Answer


2 Answers

If the general case is that you are just waiting for this other service to start up, then you may as well use the approach of having a "Ping" method on your interface that does nothing, and retrying until this starts responding.

We do a similar thing: we try and call a ping method in a loop at startup (1 second between retries), recording in our logs (but ultimately ignoring) any TargetInvocationException that occur trying to reach our service. Once we get the first proper response, we proceed onwards.

Naturally this only covers the startup warmup case - the service could go down after a successfull ping, or it we could get a TargetInvocationException for a reason other than "the service is not ready".

like image 99
Rob Levine Avatar answered Oct 20 '22 00:10

Rob Levine


You could have the service signal an event [Edited-see note] once the service host is fully open and the Opened event of the channel listener has fired. The Application would wait on the event before using its proxy.


Note: Using a named event is easy because the .NET type EventWaitHandle gives you everything you need. Using an anonymous event is preferable but a bit more work, since the .NET event wrapper types don't give you an inheritable event handle. But it's still possible if you P/Invoke the Windows DuplicateHandle API yourself to get an inheritable handle, then pass the duplicated handle's value to the child process in its command line arguments.

like image 43
Chris Dickson Avatar answered Oct 20 '22 00:10

Chris Dickson