Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
547 views
in Technique[技术] by (71.8m points)

.net - How to heal faulted WCF channels?

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...