新ServiceHost的地址总是和旧的一样?

时间:2014-06-18 14:21:51

标签: .net wcf .net-4.5

我有以下测试代码,首先尝试在无效地址上打开ServiceHost,然后当它出现故障时调用Abort()Dispose(后者可能不需要) 。然后它创建一个新的ServiceHost并尝试在另一个(有效)地址上打开它,但它仍然会生成错误,说明旧地址无效。

class Program
{
   static void Main(string[] args)
   {
      TestHost("net.tcp://0.0.0.1:8081/TestUri");
      TestHost("net.tcp://0.0.0.0:8081/TestUri");
   }

   static void TestHost(string address)
   {
      ServiceHost host = null;
      try
      {
         host = new ServiceHost(typeof(MyContract), new Uri(address));
         host.Open();
         Console.WriteLine("Host opened successfully");
         host.Close();
      }
      catch (Exception ex)
      {
         if (host != null)
         {
            host.Abort();
            ((IDisposable)host).Dispose();
         }
         Console.WriteLine(ex.Message);
      }
   }
}

[ServiceContract]
public interface IMyContract
{
   [OperationContract]
   void Method();
} 

class MyContract : IMyContract
{
   public void Method()
   {
      Console.WriteLine("Method Called");
   }
} 

这会生成以下输出:

A TCP error (10049: The requested address is not valid in its context) occurred while listening on IP Endpoint=0.0.0.1:8081.
A TCP error (10049: The requested address is not valid in its context) occurred while listening on IP Endpoint=0.0.0.1:8081.

请注意,两个错误中的端点都是相同的。 (如果我反向操作,第一个调用将成功,第二个调用将失败。)

这里似乎是一些缓存,但是如何清除它并让新的ServiceHost使用我提供的地址而不是旧地址?!

2 个答案:

答案 0 :(得分:2)

我不确定我是否也有很多帮助,除了指出其他人遇到类似问题但没有明显的解决方案。

建议:我发现对Close()的调用不会立即关闭整个堆栈,直到实际的套接字;它会在几秒钟后发生。通常这表示当您尝试在关闭端口后立即重新打开端口时,端口正在使用时会出现错误。我想知道你的测试代码中是否有类似的东西,第二个调用是试图重新打开以前的主机,因为它仍然在某个地方浮动,直到它被整理。尝试在调用TestHost和/或强制垃圾收集之间加入延迟,看看是否会改变行为。

一个问题:您是否需要绑定到特定的IP地址?在什么情况下它可能无效并且您可以重试不同的地址?你能绑定到所有地址(例如:net.tcp:// localhost:8081 / TestUri)?

答案 1 :(得分:0)

我不确定为什么会发生这种情况,但是绕过它的方法是在有效调用的URI中指定一个端口。

host = new ServiceHost(typeof(MyContract), new Uri("net.tcp://0.0.0.0:8081/TestUri"));

或者您可以在第一次通话时指定特定端口。