Tagged: WCF

WCF Best Practices

  1. Don’t put ServiceHost or client proxies in using statement as the Dispose can throw an exception, masking the original thrower from the Open Cacall
  2. Use FaultException for service side operation specific exceptions
  3. Implement IExtensibleDataObject for extensibility
  4. Avoid XmlSerializer + MessageContracts – only for interop and REST services
  5. Use SOAP for services that your own code will consume and REST for public operations.

When to use to IDisposable pattern

Answer: Whenever unmanaged resources need to be cleaned up. If you see class implements IDisposable then it contains unmanaged resouces.

Implementation details can be found here. The main components are

1) Destructor calls a dispose method with a flag to indicate that managed resources cleanup request is not required.

2) Add a dispose method that checks the flag to ensure managed resources are not cleaned up twice. Also cleans up unmanaged resources

3) Dispose function implementation that calls the dispose method with a flag to indicate that managed resources cleanup request is required. Note that  GC.SuppressFinalize is called to ensure the finaliser isn’t called that would otherwise cleanup the managed resources

Extra Note: using the using() encapsulation is not recommended for WCF client side proxies, since a number of exceptions can be thrown when it falls out of scope and calls the close method. Details here

Recommended deployment WCF TCP binding stack

Aborted channels in WCF can be caused by a range of issues. In most cases you just need to turn on WCF tracing and/or exception debugging to find the cause of the problem. However sometimes that doesn’t help and it may be caused by your binding settings. According to a post in this link; one of the following settings in this production ready custom binding (or perhaps all 😉 ) might help you get out of your bind (haha :P).

       reliableSession = New ReliableSessionBindingElement()

        reliableSession.Ordered = False

        reliableSession.InactivityTimeout = New TimeSpan(0, 60, 0)

        reliableSession.MaxPendingChannels = 100

        reliableSession.MaxTransferWindowSize = 16 ‘max pending messages

        reliableSession.AcknowledgementInterval = New TimeSpan(0, 0, 12) ‘acknowledge every 12 seconds (my personal choice)

        reliableSession.FlowControlEnabled = True ‘don’t send while destination buffer is full

        reliableSession.MaxRetryCount = 3

        transport = New TcpTransportBindingElement()

        transport.TransferMode = TransferMode.Buffered ‘streaming won’t work for us in the general case

        transport.MaxBufferSize = &H100400 ‘1 meg (plus extra)

        transport.MaxReceivedMessageSize = &H100400

        transport.ListenBacklog = 100

        transport.ConnectionPoolSettings.MaxOutboundConnectionsPerEndpoint = 100

        transport.MaxPendingAccepts = 100

        transport.MaxPendingConnections = 100

        transport.MaxBufferPoolSize = 100

        encoding = New BinaryMessageEncodingBindingElement()

        encoding.ReaderQuotas.MaxArrayLength = Integer.MaxValue

        encoding.ReaderQuotas.MaxBytesPerRead = Integer.MaxValue

        encoding.ReaderQuotas.MaxNameTableCharCount = Integer.MaxValue

        encoding.ReaderQuotas.MaxStringContentLength = Integer.MaxValue

        binding = New CustomBinding(encoding, reliableSession, transport)

        binding.CloseTimeout = New TimeSpan(0, 0, 5)

        binding.ReceiveTimeout = TimeSpan.MaxValue

        binding.OpenTimeout = New TimeSpan(0, 0, 30)

        binding.SendTimeout = New TimeSpan(0, 0, 30)

WCF async issues? – things to consider (with some redundancies)

Chaining WCF calls – increase threadpool thread count

Limit of threads in service call – again thread count in threadpool if it’s being used and/or the WCF throttling limits

How to throttle a Wcf service, help prevent DoS attacks, and maintain Wcf scalability

Dedicated thread or a Threadpool thread? – use threadpool for async calls

Monitoring the threadpool

WCF async callback exception – safe handle has been closed

It’s isn’t a good idea to close a handle returned from an asynchronous WCF handle ;). ….just handle the closing of the proxy; unless you enjoy catastrophically bringing down .NET processes.

Unhandled Exception: System.Runtime.CallbackException: Async Callback threw an exception. —> System.ObjectDisposedException: Safe handle has been closed
at System.Runtime.InteropServices.SafeHandle.DangerousAddRef(Boolean& success)
at System.StubHelpers.StubHelpers.SafeHandleAddRef(SafeHandle pHandle, Boolean& success)
at Microsoft.Win32.Win32Native.SetEvent(SafeWaitHandle handle)
at System.Threading.EventWaitHandle.Set()
at System.Runtime.AsyncResult.Complete(Boolean completedSynchronously)
at System.Runtime.AsyncResult.Complete(Boolean completedSynchronously, Exception exception)
at System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.FinishEnsureOpen(IAsyncResult result, Boolean completedSynchronously)
at System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.EnsureOpenCallback(IAsyncResult result)
at System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
at System.Runtime.AsyncResult.Complete(Boolean completedSynchronously)
— End of inner exception stack trace —

WCF server side exception handling best practice

If the service calls an object or if the service itself throws an exception it can bring down the service, so it’s important to handle them. Rather than error masking with try catch statements, with WCF it’s best to make use of the IErrorHandler.

Simply implement the interface on your service contract and then you’ll be able to mask and report errors or turn the exceptions into faults. Details can be found here.