前一段时间我看到一篇有趣的文章,解释了将 HttpClient
在 using block 中将在代码执行但不关闭 TCP 套接字时处理该对象,并且 TCP 状态最终将进入 TIME_WAIT 并在该状态列表中停留 4 分钟以进行进一步的事件(默认).
所以基本上多次使用它:
using(var client = new HttpClient())
{
//do something with http client
}
导致许多打开的 TCP 连接处于TIME_WAIT。
你可以在这里阅读整篇文章:
You're using HttpClient wrong and it is destabilizing your software
所以我想知道如果我对 ClientBase<TChannel>
做同样的事情会发生什么当您右键单击项目并选择添加 添加服务引用时,由 Visual Studio 创建的派生服务类。 . 并实现了这个:
//SomeServiceOutThere inherits from ClientBase
using (var service = new SomeServiceOutThere())
{
var serviceRequestParameter = txtInputBox.Text;
var result = service.BaddaBingMethod(serviceRequestParameter);
//do some magic (see Fred Brooks quote)
}
但是,我无法重新创建完全相同的行为,我想知道为什么。
- 我创建了一个小型桌面应用程序并添加了对 IIS 托管的 WCF 服务的引用。
- 接下来,我添加了一个按钮,基本上通过上面显示的 using 代码块调用代码。
- 第一次访问该服务后,我为 IP 运行 netsat,结果如下:
- 到目前为止一切顺利。我再次点击按钮,果然,新的连接建立了,而第一个连接进入了TIME_WAIT状态:
- 但是,在此之后,每次我访问该服务时,它都会使用ESTABLISHED 连接,并且不再像
HttpClient
中那样打开。演示(即使将不同的参数传递给服务,但保持应用程序运行)。
似乎 WCF 足够聪明,可以意识到已经建立了与服务器的连接,并使用它。
有趣的是,当我重复上述过程,但在每次调用服务之间停止并重新启动应用程序时,我确实得到了与 HttpClient
相同的行为。 :
ClientBase
还有一些其他潜在问题(例如 see here ),我知道如果服务流量相对较低或服务器设置为大量最大连接,临时打开套接字可能根本不是问题,但我仍然希望能够可靠地测试这是否会成为问题,以及在什么条件下(例如,正在运行的 Windows 服务与 WCF 服务相比较桌面应用程序)。
有什么想法吗?
最佳答案
WCF 内部不使用 HttpClient
。 WCF 可能使用 HttpWebRequest
,因为该 API 当时可用,而且它可能会快一点,因为 HttpClient
是它的包装器。
WCF 适用于高性能用例,因此他们确保重用 HTTP 连接。在我看来,默认情况下不重用连接是 Not Acceptable 。这是 HttpClient
的错误或设计问题。
4.6.2 Desktop .NET Framework 在 HttpClienthandler.Dispose
中包含这一行:
ServicePointManager.CloseConnectionGroups(this.connectionGroupName);
由于此代码不在 CoreClr 中,因此没有相关文档。我不知道为什么要添加这个。它甚至有一个错误,因为 this.connectionGroupName = RuntimeHelpers.GetHashCode(this).ToString(NumberFormatInfo.InvariantInfo);
在 ctor 中。两个 connectionGroupName
可能会发生冲突。这是获取本应唯一的随机数的糟糕方法。
如果重新启动进程,则无法重用现有连接。这就是您看到旧连接处于 TIME_WAIT
状态的原因。这两个过程是无关的。因为它们(和操作系统)中的代码知道它们没有以任何方式合作。跨进程重启也很难保存 TCP 连接(但有可能)。据我所知,没有任何应用可以做到这一点。
您是否经常启动流程,以至于这可能会成为一个问题?不太可能,但如果是,您可以应用一种通用解决方法,例如减少 TIME_WAIT
持续时间。
复制这个很容易:只需在一个循环中启动 100k 个测试过程。
关于c# - WCF 的 ClientBase<TChannel> 在 Disposed 时如何处理 TCP 连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40058217/