首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >单元测试时ServiceHost的地址冲突

单元测试时ServiceHost的地址冲突
EN

Stack Overflow用户
提问于 2009-09-11 16:17:29
回答 2查看 2.1K关注 0票数 1

我有一个小的WCF托管引擎,我正在编写,它将动态创建基于.config文件的ServiceHosts。一般的想法是允许我们在运行时删除现有服务,以及添加新服务,而不必使所有服务离线。

我遇到了一个问题,单元测试表明这可能并不像听起来那么容易。对于任何给定的端点,似乎只有一个ServiceHost (即使一个服务的多个不同端点可能存在于单个ServiceHost中)。这通常不是问题,但是当服务需要重新配置时,关闭原始ServiceHost实际上并不会终止该端点地址的注册。尝试为同一服务创建另一个ServiceHost (这意味着使用相同的终结点)失败,出现以下异常:

代码语言:javascript
复制
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(),但这实际上并没有破坏它仍然挂在内存中的服务host...so。我不知道是GC正在清理旧的服务主机,还是not...the问题在最初发生后仍然存在(就我所能确定的最好情况而言,到目前为止我已经等待了大约30分钟)。

我的system.serviceModel配置文件如下:

代码语言:javascript
复制
  <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>
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2009-11-11 13:31:47

来提供这个问题的答案,以防其他人遇到这个问题。这个问题实际上有两个原因,如下所示:

1)在单元测试期间,如果遇到异常,通常会在ServiceHost关闭之前中断正在测试的代码。这使得ServiceHost绑定到特定的端点。这会导致执行同一段代码的所有后续测试失败。当我使用SubSpec和xUnit进行BDD时,一个测试用例( BDD术语中的关注点)执行每个测试的单个断言,并且一个测试用例可以包含多达12个或更多的断言。

2)注意MEX端点。每项服务只能存在一次MEX终结点。最初,我创建了一个http和net.tcp mex端点。然而,这导致了一个问题,因为MEX端点的任何一个实例启动后都会抛出异常。一般来说,如果您使用MEX端点,HTTP是最有用的协议,除非有一些物理基础设施问题阻止您这样做。

一般来说,在ServiceHost上调用Close()方法将完全解除绑定,从而允许以前绑定到其端点的任何地址再次可用。有时关闭可能需要一段时间,在极少数情况下,可能会抛出异常。如果您正在使用SubSpec进行BDD,并遵循每次测试一个断言的规则,则在一个测试中引发的阻止ServiceHosts闭包的异常将导致所有后续测试失败。

票数 3
EN

Stack Overflow用户

发布于 2009-09-11 17:08:35

一种方法是在每次启动服务主机的URL时附加一个Guid,并使用工厂方法,该方法既启动ServiceHost实例又返回客户端通道,以便客户端知道要使用哪个URL。

IDesign的InProcFactory示例使用此方法,因此您可以按原样使用它:

http://www.idesign.net/idesign/DesktopDefault.aspx?tabindex=5&tabid=11

请注意,您必须在IDesign的站点上注册才能下载示例,他们会偶尔向您发送关于培训之类的公告,但这并不是太多。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1411923

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档