mafu
mafu

Reputation: 32680

How should I reopen a failed WCF channel?

I'm using a client-side proxy object to access a WCF channel. To access any of the service methods, the call is wrapped in a try-catch to ensure well defined behavior.

However, once the channel is nonfunctional for any reason, I would like to reopen it. What is the proper way to do that? I see two questions:

1. When to check

2. How to perform the reopen

This troubled me quite a bit. If i understand the situation correctly, I have to handle every possible state separately. Also, I possibly have to avoid threading issues such as opening the channel twice if two method calls were received at the same time (only applies to option A of the previous point).

I recall there being a lot of things to consider when reopening a channel. It is required to differentiate between Faulted and Closed (and Closing), order of operations does matter, and certain operations invalidate the object (?).

And as if that were not enough trouble, the MSDN apparently provides wrong example code (missing cases, sloppily dealing with edge conditions etc.) so I can't rely on that at all.

Upvotes: 3

Views: 3758

Answers (2)

mafu
mafu

Reputation: 32680

For reference, this is what I currently use:

class FooProxy : IFoo
{
    private readonly object _Sync = new object ();
    private IFoo Channel;

    public FooProxy ()
    {
    }

    private void CreateChannel ()
    {
        lock (_Sync) {
            if (Channel != null) {
                if (((ICommunicationObject) Channel).State == CommunicationState.Opened) {
                    return;
                }
            }

            // Attempt to create new connection
            var factory = new ChannelFactory<IFoo> (...);
            var channel = factory.CreateChannel ();

            ((ICommunicationObject) channel).Faulted += (s, e) => ((ICommunicationObject) Channel).Abort ();

            try {
                ((ICommunicationObject) channel).Open ();
            }
            catch (EndpointNotFoundException) {
                // dont worry
                return;
            }

            Channel = channel;
        }
    }

    public string DoStuff ()
    {
        // try to create a channel in case it's not there
        CreateChannel ();

        try {
            return Channel.DoStuff ();
        }
        // something goes wrong -> ensure well defined behavior
        catch (CommunicationException ex) {
            return null;
        }
    }
}

Upvotes: 0

Ladislav Mrnka
Ladislav Mrnka

Reputation: 364279

Channel cannot be reopened. The only valid state shift once the channel is in Faulted state is calling Abort. Once you abort the current channel / proxy you can start the new one and establish new connection to the server.

Upvotes: 3

Related Questions