Recovering from a CommunicationObjectFaultedException in WCF
Asked Answered
M

1

15

I have a client app that tries every 10 seconds to send a message over a WCF web service. This client app will be on a computer on board a ship, which we know will have spotty internet connectivity. I would like for the app to try to send data via the service, and if it can't, to queue up the messages until it can send them through the service.

In order to test this setup, I start the client app and the web service (both on my local machine), and everything works fine. I try to simulate the bad internet connection by killing the web service and restarting it. As soon as I kill the service, I start getting CommunicationObjectFaultedExceptions--which is expected. But after I restart the service, I continue to get those exceptions.

I'm pretty sure that there's something I'm not understanding about the web service paradigm, but I don't know what that is. Can anyone offer advice on whether or not this setup is feasible, and if so, how to resolve this issue (i.e. re-establish the communications channel with the web service)?

Thanks!

Klay

Mcgrody answered 6/8, 2009 at 20:43 Comment(0)
V
40

Client service proxies cannot be reused once they have faulted. You must dispose of the old one and recreate a new one.

You must also make sure you close the client service proxy properly. It is possible for a WCF service proxy to throw an exception on close, and if this happens the connection is not closed, so you must abort. Use the "try{Close}/catch{Abort}" pattern. Also bear in mind that the dispose method calls close (and hence can throw an exception from the dispose), so you can't just use a using like with normal disposable classes.

For example:

try
{
    if (yourServiceProxy != null)
    {
        if (yourServiceProxy.State != CommunicationState.Faulted)
        {
            yourServiceProxy.Close();
        }
        else
        {
            yourServiceProxy.Abort();
        }
    }
}
catch (CommunicationException)
{
    // Communication exceptions are normal when
    // closing the connection.
    yourServiceProxy.Abort();
}
catch (TimeoutException)
{
    // Timeout exceptions are normal when closing
    // the connection.
    yourServiceProxy.Abort();
}
catch (Exception)
{
    // Any other exception and you should 
    // abort the connection and rethrow to 
    // allow the exception to bubble upwards.
    yourServiceProxy.Abort();
    throw;
}
finally
{
    // This is just to stop you from trying to 
    // close it again (with the null check at the start).
    // This may not be necessary depending on
    // your architecture.
    yourServiceProxy = null;
}

There was a blog article about this, but it now appears to be offline. A archived version is available on the Wayback Machine.

Venice answered 6/8, 2009 at 20:51 Comment(6)
+10 if I could - wow, this behaviour is entirely under the radar, never would have worked out what was going on if I hadn't stumbled on this answer.Rawhide
Bravo! I implemented a version of this as an extension method: TryDispose on the proxy class for use by others.Justinn
@Moby's Stunt Double - are you able to share your code?Goniometer
Codepaste-Link: Page cannot be found.Therapist
for anyone here you can use the way back machine for some more detail. web.archive.org/web/20170625141905/http://…Quimby
Thanks @RichardHousham, I've added the link to the answer.Venice

© 2022 - 2024 — McMap. All rights reserved.