Search code examples
c#wcfasp.net-corechannelfactory

ASP.NET Core ChannelFactory Leaving Connections Open


I've started converting an existing ASP.Net Framework project to an ASP.NET Core project. One of the components was a WCF Wrapper using ChannelFactory. I was able to convert it to run in the ASP.NET Core project without much trouble. However, while testing the new ASP.NET Core project I noticed connections were building up. To investigate the issue I created two console projects (one ASP.NET Framework and the other ASP.NET Core) with a very basic ChannelFactory setup:

 BasicHttpBinding myBinding = new BasicHttpBinding();
 EndpointAddress myEndpoint = new EndpointAddress("http://localhost:63566/Service1.svc");
 using (ChannelFactory<IService1> myChannelFactory = new ChannelFactory<IService1>(myBinding, myEndpoint))
 {
     IService1 instance = myChannelFactory.CreateChannel();
     Console.WriteLine(instance.GetData(x));
 }

The above code is called 5 times. The output of each service call is sent to the console along with the NETSTAT output for the process.

The output for the ASP.NET Framework was:

ASP.NET Framework Output

The output for the ASP.NET Core was:

ASP.NET Core Output

As you can see the connections remain open for the ASP.NET Core version. The code for both projects were identical. As far as I can tell, the main difference is ASP.NET Framework will be using System.ServiceModel 4.0.0.0 and ASP.NET Core is using System.ServiceModel.Primitives 4.1.1.0. Is this a bug, an intended feature, or am I doing something silly? I'd be very surprised if it's a bug, but we have a very high throughput and connections remaining open could cause issues in production.

UPDATE

I've added extra code to close the channel and add logging to the console on the Close events of the ChannelFactory and Channel. The code is now:

    public void CallIt(int x)
    {
        BasicHttpBinding myBinding = new BasicHttpBinding();
        EndpointAddress myEndpoint = new EndpointAddress("http://localhost:63566/Service1.svc");
        using (ChannelFactory<IService1> myChannelFactory = new ChannelFactory<IService1>(myBinding, myEndpoint))
        {
            IService1 instance = myChannelFactory.CreateChannel();
            myChannelFactory.Closed += ChannelFactory_Closed;
            ((IClientChannel)instance).Closed += Channel_Closed;
            Console.WriteLine(instance.GetData(x));
            ((IClientChannel)instance).Close();
        }
    }

    private void ChannelFactory_Closed(object sender, EventArgs e)
    {
        Console.WriteLine("Factory closed.");
    }

    private void Channel_Closed(object sender, EventArgs e)
    {
        Console.WriteLine("Channel closed.");
    }

The image links above have been updated with the new outputs. I would add new ones, but am unable until I have more reputation.


Solution

  • I logged an issue with the developers and they explained why it behaves like this. Basically the full framework uses HttpWebRequest and the ASP.Net Core version uses HttpClient. I knew we shouldn't be disposing HttpClient as it causes port exhaustion, but not that the ASP.NET Core ChannelFactory uses HttpClient.