title: C# .NET Server polling multiple connections - is there a better way?
body: <p>I'm developing a TCP server in .NET C#. It uses asynchronous I/O (I/O completion) to handle a large number of clients simultaneously. Right now I have all the TCP connections in a list, which I pass through continuously looking for a change in the state machine of any particular connection. The state machine for a given connection is updated once the I/O completion sets certain flags.</p>
  
  <p>I'm sure there is a better way to do this - the current implementation is very processor intensive since I am not blocking waiting for an update, but rather polling without throttling. I don't really care if my server is wasting cycles, but I'm guessing it's poor design. I'm trying to find a way to process a particular connection only when I/O completion signals there is something to handle, and wait (i.e. sleep) when not. Can anybody suggest a good way to do this?</p>
  
  <p>I was thinking that some thread synchronization things might work where the main thread that is looping waits for any I/O completion to release it. However, I/O completion is sometimes executed using the calling thread (when data is immediately available, etc.) so this would cause problems with this solution.</p>
  
  <p>Anything you can suggest would be much appreciated!</p>
  
  <p>Here is the (simplified) loop that is executed by the main thread (rgClient is the list of clients):</p>
  
  <pre><code>//Do communications on each client we currently have connected.
  //This loops runs backwards so we can delete elements on the fly
  //without have to iterate through more than once.
  lock (rgClient)
  {
      for (i = rgClient.Count - 1; i &gt;= 0; i--)
      {
          if (!rgClient[i].DoComm())
          {
              rgClient[i].DoClose();
              rgClient.RemoveAt(i);
          }
      }
  }
  </code></pre>
  
  <p>DoComm() performs an update on the state machine for the connection, which involves executing the current state's activities, and then transitioning to a new state if necessary. Here is the state class for sending a simple "ack" packet:</p>
  
  <pre><code>class StateAck : State
  {
      public StateAck(TextBox txtOutputExt, Form fmOwner)
          : base(txtOutputExt, fmOwner)
      {
          fWriting = false;
      }
  
      public override bool DoExecute(out Type tpNextState)
      {
          PktAck pkt;
  
          if (!base.DoExecute(out tpNextState))
          {
              return false;
          }
  
          //Start a write if we haven't yet
          if (!fWriting)
          {
              pkt = new PktAck();
              fWriting = true;
  
              return FPutPkt(pkt.rgbSerialize());
          }
  
          //Is the read finished / has an error occurred?
          if (fDataErrorWrite)
          {
              return false;
          }
  
          //Process the data
          if (fDataWritten)
          {
              tpNextState = typeof(StateIdle);
          }
  
          return true;
      }
  
      private bool fWriting;
  }
  </code></pre>
  
  <p>Execution passes through DoExecute() every time DoComm() is called from the main thread. 99% of the time, nothing actually occurs. When the write (which is initiated by calling FPutPkt()) completes, a flag will signal this and then the next state is set to "idle". What I want to do, is have the main thread only check clients that have finished their network activity and have something that needs updating, to avoid the constant and redundant passes through DoExecute().</p>