获取地址已在使用异常。自托管 wcf 服务

Get Address Already In Use exception. self hosted wcf service

我发现了很多关于这个问题的问题:here, here, here, and here,但无法解决我的问题。

背景:

我们有一个现有的非托管应用程序可以启动托管 winforms 应用程序。 有一个共享托管程序集,它公开非托管应用程序的可见对象,并且该程序集启动托管应用程序。 因此,ServiceHost 在 winforms 应用程序上运行,客户端在该共享程序集上运行。设置类似于 this implementation 。 该应用程序大约运行。 100个,win xp or win 7.

问题:

每隔几天我们就会得到: System.ServiceModel.AddressAlreadyInUseException 尝试启动 winforms 应用程序时。 我们 运行 netstat 但找不到任何在该端口上侦听的内容。 唯一的'solution'是重启电脑

我无法在我的开发机器上重现这个问题。但它偶尔会在生产环境中发生。

代码:

正在输入代码,希望没有拼写错误,不能复制粘贴:

服务配置(在 winform appconfig 中找到):

<system.ServiceModel>
  .
  .
    <services>
    <service name="MyService">
    <endpoint address="net.tcp://localhost:4444" binding="netTcpBinding"
       contract="IMyService"/>
    </service>
    </services>
  .
  .
<\system.ServiceModel>

服务

StartService() 从 mainform_Load

调用
private static void StartService()
{
  try
   {
      _serviceHost = new ServiceHost(typeof(MyService));
      _serviceHost.Open();
   }
  catch(Exception ex)
   {
     LogError(ex);
     ExitApp();

   }
}

private static void ExitApp()
{
  try
   {
     _serviceHost.Close();
   }
  catch(CommunicationException cex)
   {
     LogError(cex);
     _serviceHost.Abort();
   }
  finally
   {
     Application.Exit();
   }

}

客户

private static void CallMyService()
  {
    var channelFactory = new ChannelFactory<IMyService>("net.tcp://localhost:4444");
    IMyService myChannel= channelFactory.CreateChannel();
    bool error = true;
    try
     {
      myChannel.PerformOperation();
      ((IClientChannel)myChannel).Close();
      error = false;
     }
   finally
    {
      if (error)
      {
       ((IClientChannel)myChannel).Abort();
      }
    }
  }

希望我说得够清楚了,谢谢

我注意到一些对我的机器有帮助的事情:当我配置项目时,IIS Express 以某种方式生成了具有相同端口的多个地址,并在测试期间尝试启动所有地址,导致此失败。

该错误也会通过 IIS Express 任务栏图标的弹出窗口出现。我导航到它的配置文件(“用户文档\IISExpress\config\applicationhost.config”),删除了所有包含虚拟目录绑定到这些地址的'site'节点,保存并re-tried 又成功了。

希望这对你有用吗?

我们在 2015 年解决了这个问题,我现在分享答案:

由于进程之间的通信是在同一台机器上进行的,我们使用 NetNamedPipeBinding 而不是 NetTcpBinding,并且我们不再有 System.ServiceModel.AddressAlreadyInUseException 个异常。

设置如下(实际代码有点不同):

服务:

private static void StartService()
{
  try
   {
      string address = "net.pipe://localhost/MyApp/NamedPipeBindingHost";
      _serviceHost = new ServiceHost(typeof(MyService));
       NetNamedPipeBinding b = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None);
      _serviceHost.Open();
      b.OpenTimeout = TimeSpan.FromMinutes(2);
      b.closeTimeout = TimeSpan.FromMinutes(1);
      b.ReceiveTimeout = TimeSpan.FromMinutes(10);

     _serviceHost.AddServiceEndpoint(typeOf(IMyService), b, address);
     _serviceHost.Open();
   }
  catch(Exception ex)
   {
     LogError(ex);
     ExitApp();

   }
}

private static void ExitApp()
{
 try
 {
   _serviceHost.Close();
 }
catch(CommunicationException cex)
 {
   LogError(cex);
   _serviceHost.Abort();
 }
finally
 {
   Application.Exit();
 }

}

客户:

private static void CallMyService()
  {
    string address = "net.pipe://localhost/MyApp/NamedPipeBindingHost";
    EndpointAddress ep = new EndpointAddress(adress);

    var channelFactory = new ChannelFactory<IMyService>(GetNamedPipeBindings(), ep);
    IMyService myChannel= channelFactory.CreateChannel();
    bool error = true;
    try
     {
      myChannel.PerformOperation();
      ((IClientChannel)myChannel).Close();
      error = false;
     }
   finally
    {
      if (error)
      {
       ((IClientChannel)myChannel).Abort();
      }
    }
  }

private NamedPipeBinding GetNamedPipeBindings()
{
  NamedPipeBinding  binding = new NamedPipeBinding (NetNamedPipeSecurityMode.None);

  binding.OpenTimeout = TimeSpan.FromMinutes(2); 
  b.closeTimeout = TimeSpan.FromMinutes(1);
  b.SendTimeout = TimeSpan.FromMinutes(10);

  return binding;
}