AvocadoSoftware.com

Software For Hardcore Developers
Welcome to AvocadoSoftware.com Sign in | Join | Help
in Search

Derick Baileys old blog archives - go to derickbailey.com for new contents

WCF "The Pipe has been ended" error fixed! Always close your client channel.

Per my Previous Post on the subject, I was running into constant error with WCF. Whenever my service instance was released, Windows Communication Foundation would throw this horrible exception immediately after:

System.ServiceModel.CommunicationException: There was an error reading from the pipe: The pipe has been ended. (109, 0x6d). ---> System.IO.IOException: The write operation failed, see inner exception. ---> System.ServiceModel.CommunicationException: There was an error reading from the pipe: The pipe has been ended. (109, 0x6d). ---> System.IO.PipeException: There was an error reading from the pipe: The pipe has been ended. (109, 0x6d).
   at System.ServiceModel.Channels.PipeConnection.OnAsyncReadComplete(Boolean haveResult, Int32 error, Int32 numBytes)
   --- End of inner exception stack trace ---
   at System.ServiceModel.AsyncResult.End[TAsyncResult](IAsyncResult result)
   at System.ServiceModel.Channels.ConnectionStream.EndRead(IAsyncResult asyncResult)
   at System.Net.FixedSizeReader.ReadCallback(IAsyncResult transportResult)
   --- End of inner exception stack trace ---
   at System.Net.Security.NegotiateStream.EndRead(IAsyncResult asyncResult)
   at System.ServiceModel.Channels.StreamConnection.EndRead()
   --- End of inner exception stack trace ---
   at System.ServiceModel.AsyncResult.End[TAsyncResult](IAsyncResult result)
   at System.ServiceModel.Channels.FramingDuplexSessionChannel.EndTryReceive(IAsyncResult result, Message& message)
   at System.ServiceModel.Dispatcher.DuplexChannelBinder.EndTryReceive(IAsyncResult result, RequestContext& requestContext)
   at System.ServiceModel.Dispatcher.ErrorHandlingReceiver.EndTryReceive(IAsyncResult result, RequestContext& requestContext)

The issue - Garbage collection of my Channel object

The issue turned out to be how I was instantiating objects in the client and how I was allowing the GC to automatically collect my objects when I was done using them. I am using ChannelFactory<t> to create my client connections. I was not closing the channel after the call completed. A quick DynamicProxy implementation fixed that and I'm no longer getting this error.

Here is a basic code sample of how to properly open and close a WCF service object with the ChannelFactory<t>:

//setup and configure the factory, here
ChannelFactory<IMyObject> factory = new ChannelFactory<IMyObject>(myBinding, myServiceUrl);

//get the client proxy object
IMyObject myObject = ChannelFactory.CreateChannel();

// do the calls to myObject here...
myObject.DoSomething();

//close the channel
IChannel channel = IMyObject as IChannel;
if (channel != null)
  channel.Close();

Hiding the channel close via DynamicProxy

I'm using a dependency injection system to create my objects, so I am not able to close the channel directly from the client code. A quick dynamic proxy implementation wraps up the channel closing for me.

public class WCFChannelInterceptor : IInterceptor
{
    #region IInterceptor Members

    public void Intercept(IInvocation invocation)
    {

        //proceed with the invocation
        invocation.Proceed();

        CloseChannel(invocation);
    }

    #endregion

    private void CloseChannel(IInvocation invocation)
    {
        //close the channel, if we can
        IChannel channel = invocation.InvocationTarget as IChannel;
        if (channel != null)
        {
            channel.Close();
        }
    }

}

A huge relief! and thanks you's

A big thanks to Robert O'Neil - a coworker - for pointing me in the right direction ("sounds like the channel is getting destroyed by the client without the server knowing that. are you closing the channel in the client?"). You helped me solve 3 days worth of research and headache, in less than 2 hours!

And a huge thanks to Hammett and the team at CastleProjet.org ... without Castle.DynamicProxy, I would have spent the next 3 days restructuring my code to handle this properly.

Published Wednesday, September 26, 2007 12:06 PM by dredge
New Comments to this post are disabled

This Blog

Post Calendar

<September 2007>
SuMoTuWeThFrSa
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

Advertisement

News

this is my old blog archives - go to http://derickbailey.com for updates

Syndication

Advertisement

Powered by Community Server, by Telligent Systems