سؤال

I have several WCF Services in my WPF application, I open them using this method:

private void StartSpecificWCFService(IService service, string url, Type serviceInterfaceType)
{
    ServiceHost serviceHost = new ServiceHost(service, address);
    serviceHost.AddServiceEndpoint(serviceInterfaceType, new NetNamedPipeBinding(), url);
    serviceHost.Open();
    //sign to serviceHost.Faulted ??
    _wcfServicesHolder.Add(serviceHost); //A dictionary containing all my services
}

the services attributes are:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]

The services are logging service and event service, they get many calls from other processes.. I use namedpipes since it is the fastest and the processes run on SAME computer.

My question is - How do i maintain these services to be up all time ?

  1. Poll timer that iterate _wcfServicesHolder and check if service is opened
  2. sign to serviceHost.Faulted event.

And after a service is in faulted state, does the client (on different process) must be re-created ? or it can still broadcast message on same channel ?

The exception i receive is:

There was no endpoint listening at net.pipe://localhost/LoggingService that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details
هل كانت مفيدة؟

المحلول

Why do the services have InstanceContextMode = InstanceContextMode.Single with concurrent thread access? Do the services hold some kind of in-memory thread-safe state? If not, it may be well worth trying to re-factor the services to use InstanceContextMode.PerCall. This should be your default and preferred choice when configuring WCF services - WCF is primarily a technology for implementing a service-orientated architecture, and using a mode other than PerCall violates the Statelessness principle of SO Design Principles.

In support of this, if you have a server-side fault with InstanceContextMode.Single, this suggests something has gone seriously wrong in the service. Any state that you maintained within the service will be lost - clients can not expect just to re-connect and resume as normal.

Whatever InstanceContextMode you end up using, your channel will fault if it remains open with no clients connecting to it for a certain length of time. Over TCP (or any protocol that explicitly exposes a reliable session), you can specify the inactivity timeout on the reliable session, but you have no such option using pipes.

With pipes, leaving a channel open longer than the configured timeout, will fault the channel rendering it useless. You can subscribe to the channel faulted event, and recreate the proxy if you are interested in keeping a channel open to the service for the lifetime of your application. As you suggest - another option is to keep polling along the channel to keep it alive.

نصائح أخرى

In order to keep your service host up, go with your #2 option (Subscribe to the faulted event on the service host). When faulted, you need to Abort the servicehost, new up a fresh instance, rewire the faulted event handler, and open the service host.

There's not much official documentation on this scenario, but here's an old post from an msdn blog describing what you're looking for.

http://blogs.msdn.com/b/drnick/archive/2007/01/16/restarting-a-failed-service.aspx

As to the client, it also will need to recreate its channel to the server when said channel is faulted.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top