views:

383

answers:

2

I am working on a project that is using NetTcp bindings for talking to some WCF services. When first starting out we took a bad practice example from another application that made WCF calls by using the following:

EntityObject sample = new ServiceProxy().GetEntity();

That worked great until we realized WCF was holding onto the connections even though the aspx page had been sent to the client (which I naively assumed would clean up any connections). While the connections were held on causing things to eventually slow down, ELMAH logged any errors and sent us full stack traces. To resolve the performance issues we changed to this:

using (ServiceProxy proxy = new ServiceProxy())
{
     sample = proxy.GetEntity();
}

This made performance rock comparatively. The downside to this method is whenever an error is received on the proxy the only thing ELMAH can catch is that the channel is now faulted. We then have to dig through logs (the WCF ones setup with sharedListeners in ) to figure out what happened and if it's a serialization error the odds of actually find it become much lower, despite the listeners being setup on both client and server. I've explored the IErrorHandler interface and am going to add support for it to our services, but I was wondering if there are other ways to get detailed errors out of WCF instead of it just saying it faulted with no real information as to why it faulted. This would be especially beneficial if it dies on serializing the object that it could tell us WHY it couldn't serialize.

+1  A: 

I think if you call Close() explicitly on the proxy, and put that in a try-catch, you'll get what you want.

See especially this sample:

http://msdn.microsoft.com/en-us/library/aa355056.aspx

Brian
That looks exactly like what I am looking for. Thanks for the help.
digitall
+1  A: 

Well, you can tell the WCF servive to send back more information than just "something bad happened" by using the serviceDebug behavior.

<system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ExceptionDetails">
          <serviceDebug includeExceptionDetailInFaults="True" />
        </behavior>
      </serviceBehaviors>
    </behaviors>

This is OK as long as it's a dev/test environment, or an in-house app. But really, service error should be caught (and logged) on the server side - you're on the right path with the IErrorHandler interface.

The client needs to handle client-side exceptions, like TimeoutException and CommunicationException to deal with security exceptions or networks going down and such. Just standard .NET exception handling, really.

Also, the using() is a good idea in general - but not necessarily here, since you could encounter an exception when the ServiceProxy is being disposed of (at the end of the using() {} block), and that won't be caught in this case. You might just need to use a try {...} catch {...} finally {...} block for your service proxies instead.

Marc

marc_s
We're actually using the includeExceptionDetailInFaults flag, and the exception comes back in debug, but the error is then trapped by the fact that the proxy faulted so all we end up seeing is that it faulted without any additional information.The try/catch could be an option but it certainly wouldn't be fun to change everything now. I'll have to explore it a little though.
digitall