ChannelFactory, IDisposable and Handling Faults

Tags: Knockout, pubsub, observer, MVC, jQuery, Ajax, EF, Validation, FluentValidation, Visual Studio 2010, ASP.NET, JSON, FullCalendar, Silverlight, Architecture, Vista, IIS, Generics, NHibernate, WCF, RIA Services, Visual Studio 2008, SQL, STORM!, Nullable, ChannelFactory, netTCPBinding, VSPAT, responsive, design, HTML5, CSS3, MVC WebAPI, MVC 4, WebAPI, JQuery Mobile, ScheduleWidget, recurring events, Ninject, Pluggable, CQRS DDD, Windows

In my last post (Poor Man's Publish-Subscribe WCF Service) I used the ChannelFactory to build a communication channel that I could use to call a WCF service. There's something about that implementation that I wanted to explain in more detail. Notice the try-catch block surrounding the using statement:

try
{
    var channel = BuildSubscriberClientChannel(subscriber);
    using (channel as IDisposable)
    {
        channel.Notify(eventCode);
    }
}
catch
{
    // in case using statement throws error
}

The ChannelFactory explicitly implements IDisposable.Dispose. And of course a call to CreateChannel returns an instance of the contract for the service. That's why I can convert the channel to IDisposable. This will force a call to Dispose, which is the same as a call to Close, when the code leaves the using block. But if an exception is thrown and the channel is faulted then you should be prepared to handle it. In my case I didn't want the exception to bubble all the way up to the client. So I wrapped it in a try-catch block. This is useful for another reason. I can let the GC take care of the faulted channel and create another one to retry the caller later.

Certainly channels are expensive to set up and tear down. But this is the cost of doing business when WCF services call each other. They have explicit boundaries and we're not dealing here with simple calls to objects on the heap. So you have to think about a strategy for what happens when the channel is faulted. In my case I wanted to build in some message durability. So in the catch block I save the message and subscriber ID in a local failed message table. Then I have a job that kicks off at regular intervals and checks the failed message table for messages. For each one it attempts to resend the message. On success it deletes the entry from the failed messages table. If the channel still faults or there is some other exception then it does nothing so that we can try again later.

Add a Comment