ASP.NET 核心 ChannelFactory 保持连接打开
ASP.NET Core ChannelFactory Leaving Connections Open
我已经开始将现有的 ASP.Net 框架项目转换为 ASP.NET 核心项目。其中一个组件是使用 ChannelFactory 的 WCF Wrapper。我可以毫不费力地将它转换为 ASP.NET 核心项目中的 运行。然而,在测试新的 ASP.NET Core 项目时,我注意到连接正在建立。为了调查这个问题,我创建了两个具有非常基本的 ChannelFactory 设置的控制台项目(一个 ASP.NET Framework 和另一个 ASP.NET Core):
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));
}
以上代码被调用了5次。每个服务调用的输出与进程的 NETSTAT 输出一起发送到控制台。
ASP.NET 框架的输出是:
ASP.NET 核心的输出是:
如您所见,ASP.NET Core 版本的连接保持打开状态。两个项目的代码是相同的。据我所知,主要区别是 ASP.NET 框架将使用 System.ServiceModel 4.0.0.0,而 ASP.NET 核心将使用 System.ServiceModel.Primitives 4.1.1.0。这是一个错误,一个预期的功能,还是我在做一些愚蠢的事情?如果这是一个错误,我会感到非常惊讶,但我们的吞吐量非常高,并且连接保持打开状态可能会导致生产出现问题。
更新
我添加了额外的代码来关闭通道并在 ChannelFactory 和 Channel 的 Close 事件上向控制台添加日志记录。现在的代码是:
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.");
}
上面的图像链接已更新为新的输出。我会添加新的,但在我有更多声誉之前我无法添加。
我与开发人员进行了 issue 记录,他们解释了为什么会这样。基本上整个框架使用 HttpWebRequest,ASP.Net Core 版本使用 HttpClient。我知道我们不应该处理 HttpClient,因为它会导致端口耗尽,但并不是 ASP.NET Core ChannelFactory 使用 HttpClient。
我已经开始将现有的 ASP.Net 框架项目转换为 ASP.NET 核心项目。其中一个组件是使用 ChannelFactory 的 WCF Wrapper。我可以毫不费力地将它转换为 ASP.NET 核心项目中的 运行。然而,在测试新的 ASP.NET Core 项目时,我注意到连接正在建立。为了调查这个问题,我创建了两个具有非常基本的 ChannelFactory 设置的控制台项目(一个 ASP.NET Framework 和另一个 ASP.NET Core):
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));
}
以上代码被调用了5次。每个服务调用的输出与进程的 NETSTAT 输出一起发送到控制台。
ASP.NET 框架的输出是:
ASP.NET 核心的输出是:
如您所见,ASP.NET Core 版本的连接保持打开状态。两个项目的代码是相同的。据我所知,主要区别是 ASP.NET 框架将使用 System.ServiceModel 4.0.0.0,而 ASP.NET 核心将使用 System.ServiceModel.Primitives 4.1.1.0。这是一个错误,一个预期的功能,还是我在做一些愚蠢的事情?如果这是一个错误,我会感到非常惊讶,但我们的吞吐量非常高,并且连接保持打开状态可能会导致生产出现问题。
更新
我添加了额外的代码来关闭通道并在 ChannelFactory 和 Channel 的 Close 事件上向控制台添加日志记录。现在的代码是:
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.");
}
上面的图像链接已更新为新的输出。我会添加新的,但在我有更多声誉之前我无法添加。
我与开发人员进行了 issue 记录,他们解释了为什么会这样。基本上整个框架使用 HttpWebRequest,ASP.Net Core 版本使用 HttpClient。我知道我们不应该处理 HttpClient,因为它会导致端口耗尽,但并不是 ASP.NET Core ChannelFactory 使用 HttpClient。