我正在编写一个小型 WCF 托管引擎,它将根据 .config 文件动态创建 ServiceHost。总体思路是允许我们在运行时删除现有服务以及添加新服务,而无需使所有服务脱机。
我遇到了一个问题单元测试,表明这可能不像听起来那么容易。对于任何给定的端点,似乎只有一个 ServiceHost 存在(即使一个服务的多个不同端点可能存在于单个 ServiceHost 中)。这通常不是问题,但是当需要重新配置服务时,关闭原始 ServiceHost 实际上并不会终止该端点地址的注册。尝试为同一服务(这意味着使用相同的端点)创建另一个 ServiceHost 失败,并出现以下异常:
System.InvalidOperationException: The ChannelDispatcher at 'net.pipe://localhost/' with contract(s) '"ITestService"' is unable to open its IChannelListener. --->
System.InvalidOperationException: A registration already exists for URI 'net.pipe://localhost/'.
我实际上在单元测试期间遇到了错误。测试将运行一个单元,该单元尽可能地完全关闭 ServiceHosts 和托管引擎。然后创建托管引擎的另一个实例,该实例尝试再次重新创建相同的 ServiceHosts 以进行不同的测试。第二次测试遇到上面的错误。我猜在调用 ServiceHost.Close() 时,它实际上并没有破坏服务主机......所以它仍然在内存中徘徊。我无法判断 GC 是否正在清理旧的服务主机……问题在最初发生后仍然存在并没有消失(据我所知,我已经能够确定……到目前为止,我已经等了大约 30 分钟。 )
我的 system.serviceModel 配置文件如下:
<system.serviceModel>
<services>
<service name="Campus.Core.ServiceModel.TestServiceStub">
<endpoint
address="net.pipe://localhost"
binding="netNamedPipeBinding"
contract="Campus.Core.ServiceModel.ITestService"
/>
</service>
</services>
</system.serviceModel>