title: TcpListener.AcceptSocket( ) behavior: gets stuck in one app upon termination, but does not in another?
body: <p>I have two TCP-server apps that are based on the same code, but for some reason exhibit different behavior and i'm ready to pull my hair out trying to figure out why.  The code pattern is as follows:</p>
  
  <pre><code>public class TcpServer
  {
      public static void Start( bool bService )
      {
          ..
          oTcpListnr= new TcpListener( ip, iOutPort );
          aTcpClient= new ArrayList( );
          bListen=    true;
          oTcpListnr.Start( );
          thOutComm=  new Thread( new ThreadStart( AcceptTcpConn ) );
          thOutComm.Name= "App-i.AcceptTcpConn";
          thOutComm.Start( );
          ..
      }
      public static void      Stop( )
      {
          bListen=    false;
  
          if(  thOutComm != null  )
          {
              thOutComm.Join( iTimeout );
              thOutComm=  null;
          }
          if(  oTimer != null  )
          {
              oTimer.Change( Timeout.Infinite, Timeout.Infinite );
              oTimer.Dispose( );
          }
      }
      public static void      AcceptTcpConn( )
      {
          TcpState    oState;
          Socket      oSocket=    null;
  
          while(  bListen  )
          {
              try
              {
          //      if(  oTcpListnr.Pending( )  )
                  {
                      oSocket=    oTcpListnr.AcceptSocket( );
                      oState=     new TcpState( oSocket );
  
                      if(  oSocket.Connected  )
                      {
                          Utils.PrnLine( "adding tcp: {0}", oSocket.RemoteEndPoint.ToString( ) );
                          Monitor.Enter( aTcpClient );
                          aTcpClient.Add( oState );
                          Monitor.Exit( aTcpClient );
  
                          oSocket.SetSocketOption( SocketOptionLevel.IP, SocketOptionName.DontFragment, true );
                          oSocket.SetSocketOption( SocketOptionLevel.Socket, SocketOptionName.DontLinger, true );
  
              //  /       oSocket.BeginReceive( oState.bData, 0, oState.bData.Length, SocketFlags.None,   //  no need to read
              //  /                               new AsyncCallback( AsyncTcpComm ), oState );            //  for output only
                      }
                      else
                      {
                          Utils.PrnLine( "removing tcp: {0}", oSocket.RemoteEndPoint.ToString( ) );
                          Monitor.Enter( aTcpClient );
                          aTcpClient.Remove( oState );
                          Monitor.Exit( aTcpClient );
                      }
                  }
          //      Thread.Sleep( iTcpWake );
              }
              #region catch
              catch( Exception x )
              {
                  bool    b=  true;
                  SocketException se= x as SocketException;
                  if(  se != null  )
                  {
                      if(  se.SocketErrorCode == SocketError.Interrupted  )
                      {
                          b=  false;
                          if(  oSocket != null  )
                              Utils.PrnLine( "TcpConn:\tclosing tcp: {0} ({1})", oSocket.RemoteEndPoint.ToString( ), se.SocketErrorCode );
                      }
                  }
                  if(  b  )
                  {
                      Utils.HandleEx( x );
                  }
              }
              #endregion
          }
      }
  }
  </code></pre>
  
  <p>I omitted exception handling in Start/Stop methods for brevity.  Variation in behavior is during program termination:  one app shuts down almost immediately while the other gets stuck in oTcpListnr.AcceptSocket( ) call.  I know that this is a blocking call, but in that case why does it not present an issue for the 1st app?</p>
  
  <p>Usage of this class cannot be any simpler, e.g. for a command-line tool:</p>
  
  <pre><code>class   Program
  {
      public static void  Main( string[] args )
      {
          TcpServer.Start( false );
          Console.Read( );
          Console.WriteLine( "\r\nStopping.." );
          TcpServer.Stop( );
          Console.WriteLine( "\r\nStopped.  Press any key to exit.." );
          Console.Read( );
      }
  }
  </code></pre>
  
  <p>Whether any clients have connected or not does not make a difference, 2nd app always gets stuck.</p>
  
  <p>I found a potential solution (commented lines) by checking TcpListener.Pending( ) prior to .AcceptSocket( ) call, but this immediately affects CPU utilization, therefore an inclusion of smth like Thread.Sleep(.) is a must.  Altogether though I'd rather avoid this approach if possible, because of extra connection wait times and CPU utilization (small as it is).</p>
  
  <p>Still, the main question is:  what may cause the same exact code to execute differently?  Both apps are compiled on .NET 4 Client Profile, x86 (32-bit), no specific optimizations.  Thank you in advance for good ideas!</p>