WCF:TCP 端点设置不正确(序言 72)

atl*_*ste 5 c# wcf

背景

我在这里有一个小服务,其工作方式如下:

  • 管理应用程序域并每天回收这些应用程序域的主要流程。
  • 此过程会启动一个应用程序域,它会生成一个 WCF 服务器。为了争论,让我们在端口 12345 上说。应用程序域可以使用大量内存。
  • 客户端在 WCF 服务器上运行请求。
  • 客户整齐地处理他们的连接。无论如何,回收通常发生在凌晨 3 点,此时没有客户端处于活动状态。

appdomain回收后,同样的端口被重新使用。这样,客户端仍然知道要连接到哪个端口。WCF 服务器是基于 TCP 的。

回收

在回收发生之前,appdomain 会进行一些清理。最重要的是,WCF servicehost 已关闭,我希望它会释放 TCP-IP 端口。更详细地:

this.serviceHost.Close();
this.serviceHost = null;

// Some other cleanup

GC.Collect(GC.MaxGeneration);
GC.WaitForFullGCComplete();
GC.WaitForPendingFinalizers();
Run Code Online (Sandbox Code Playgroud)

清理后,appdomain 停止,一秒钟后再次启动。停止应用程序域非常简单:

try
{
    System.AppDomain.Unload(this.serviceDomain);
    this.serviceDomain = null;
}
catch (CannotUnloadAppDomainException err)
{
    Console.WriteLine("Cannot unload app domain (attempt #{1}): {0}", err.Message, i + 1);
    Thread.Sleep(TimeSpan.FromSeconds(1.0));
}
catch (AppDomainUnloadedException)
{
    this.serviceDomain = null;
}
Run Code Online (Sandbox Code Playgroud)

问题

大多数时候一切正常。但是,每隔几周,回收工作正常,但无法访问 WCF 服务器。错误是:

System.ServiceModel.ProtocolException: You have tried to create a channel to a service that 
does not support .NET Framing. It is possible that you are encountering an HTTP endpoint.
---> System.IO.InvalidDataException: Expected record type 'PreambleAck', found '72'.
Run Code Online (Sandbox Code Playgroud)

我在这里发现最奇怪的是 WCF 服务器似乎正确设置了所有内容。因此,当我调用 时不会抛出任何异常serviceHost.Open();,这正是我在套接字被另一个进程劫持时所期望的。

我正在寻找的是可能的根本原因以及我可以测试以解决此问题的内容。

我尝试过的事情

问题出现在多台机器上,每隔几周发生一次。重新启动整个过程可解决此问题。

  • 谷歌……显然……
  • 我检查的第一件事是通过检查端口是否被另一个进程劫持netstat -aonb。(这似乎不太可能,但又一次......)Netstat 报告端口被 PID 4(系统)使用。当服务器按预期工作时,它报告同样的事情。
  • 任何试图制作最小测试用例的尝试都失败了。我试图每秒回收应用程序域,尝试创建长时间运行的 WCF 调用以创建延迟调用,甚至尝试使用 TcpListener 劫持端口......到目前为止没有任何尝试产生相同的错误。
  • 即使不配置客户端/服务器也不会产生相同的问题。当然,我会遇到错误,只是不是我要找的错误。