When a single ClientBase<T>
instance is used for multiple WCF service calls, it can get a channel into a faulted state (ie. when the service is down).
I would like to heal the channel automatically when the service comes up again. The only way I found is to call the following code before each method call:
if (clientBase.InnerChannel.State == CommunicationState.Faulted)
{
clientBase.Abort();
((IDisposable)clientBase).Dispose();
clientBase = new SampleServiceClientBase();
}
I got the feeling that this isn't the right way to do it. Anyone got a better idea?
Channels provide a low-level programming model for sending and receiving messages. This programming model relies on several interfaces and other types collectively known as the WCF channel model.
By default all exceptions thrown from within a service operation will be returned to the client as a FaultException object.
It is mandatory to provide the typeof property with FaultContract. Also, if no fault contract attribute is applied, the default exception that will be returned by WCF will be of type FaultException. Run the WCF test client and invoke the method. We can see the details of the custom message that we set.
You can't. Once a channel is faulted, it's faulted for good. You must create a new channel. WCF channels are stateful (in a manner of speaking), so a faulted channel means the state may be corrupted.
What you can do is put the logic you're using into a utility method:
public static class Service<T> where T : class, ICommunicationObject, new()
{
public static void AutoRepair(ref T co)
{
AutoRepair(ref co, () => new T());
}
public static void AutoRepair(ref T co, Func<T> createMethod)
{
if ((co != null) && (co.State == CommunicationState.Faulted))
{
co.Abort();
co = null;
}
if (co == null)
{
co = createMethod();
}
}
}
Then you can invoke your service with the following:
Service<SampleServiceClient>.AutoRepair(ref service,
() => new SampleServiceClient(someParameter));
service.SomeMethod();
Or if you want to use the default parameterless constructor, just:
Service<SampleServiceClient>.AutoRepair(ref service);
service.SomeMethod();
Since it also handles the case where the service is null
, you don't need to initialize the service before calling it.
Pretty much the best I can offer. Maybe somebody else has a better way.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With