获取地址已使用例外。自托管的wcf服务

时间:2015-07-23 10:26:08

标签: c# wcf

我发现了很多关于此问题的问题:herehereherehere,但无法解决我的问题。

背景

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

问题:

几天后,我们得到: 尝试启动winforms应用程序时出现System.ServiceModel.AddressAlreadyInUseException。 我们运行netstat但找不到任何在该端口上侦听的内容。 唯一的“解决方案”是重新启动电脑。

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

代码:

正在键入代码,希望没有拼写错误,无法复制粘贴:

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

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

服务

从mainform_Load

调用StartService()
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();
      }
    }
  }

我希望我很清楚,谢谢。

2 个答案:

答案 0 :(得分:0)

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

错误也会通过IIS Express任务栏图标中的弹出窗口显示。我导航到其配置文件(“用户文档 \ IISExpress \ config \ applicationhost.config”),删除了包含虚拟目录绑定到这些地址的所有“站点”节点,再次保存和重新尝试它奏效了。

希望这对你有用吗?

答案 1 :(得分:0)

我们在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;
}