2

I found numerous questions about this issue : here, here, here, and here, But could not solve my problem.

Background:

We have an existing unmanaged application that launches a managed winforms application. There is a shared managed assembly which exposes comvisible objects for the unmanaged app and that assembly launches the managed app. So the ServiceHost runs on the winforms app and the client on that shared assembly. The setup is similar to this implementation . The application runs on a approx. 100 pcs, win xp or win 7.

The problem:

once in a few days we get : System.ServiceModel.AddressAlreadyInUseException when trying to launch the winforms application. we ran netstat but could not find anything listening on that port. The only 'solution' is rebooting the pc.

I could not reproduce this problem on my dev machine. but it happens on production environment once in a while.

Code:

Code is being typed hopefully without typos, can not copy paste :

Service config (found in winform appconfig):

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

Service

StartService() is called from 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();
   }

}

Client

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

I hope i am clear enough, thanks.

Community
  • 1
  • 1
KD2ND
  • 321
  • 2
  • 15

2 Answers2

1

We solved this issue back in 2015, i am sharing the answer now:

Since the communication between the processes is on the same machine, we used NetNamedPipeBinding instead of NetTcpBinding and we got no more System.ServiceModel.AddressAlreadyInUseException exceptions.

The setup is like the following (actual code is a bit different):

Service :

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

}

Client :

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;
}
KD2ND
  • 321
  • 2
  • 15
0

Something I noticed that helped in my machine: somehow IIS Express generated multiple addresses with that same port when I was configuring the project, and tried to launch all of them during testing causing this failure.

The error would also appear via a popup from the IIS Express taskbar icon. I navigated to its config file ("User Documents\IISExpress\config\applicationhost.config"), removed all 'site' nodes that contained virtual directory bindings to those addresses, saved and re-tried again and it worked.

Hope this works for you?

Bo Ngoh
  • 133
  • 1
  • 8