title: serialport responding to EventHandler, but not ReadExisting or ReadLine?
body: <p>i have a program that's reading from serial port in c#.  i need to quickly write to a port, read from it, then close it.  i cannot leave it open.  i understand that serial ports read and write slowly, I've tried to set the ReadTimeout and WriteTimeout properties high, and added a thread.Sleep to try to drag the read and write times out for the devices.  here's a little bit of code:</p>
  
  <p>my method to write to port:</p>
  
  <pre><code>    private void CheckPorts(string testMessage)
      {
  
          foreach (string s in SerialPort.GetPortNames())
          {
              portNumber = Int32.Parse(s.Remove(0, 3));
              testSerial = new SerialPort(s, baudRate, Parity.None, 8, StopBits.One);
              if (testSerial.IsOpen)
              {
                  testSerial.Close();
              }
              testSerial.ReadTimeout = 2000;
              testSerial.WriteTimeout = 1000;
              testSerial.Open();
              if (testSerial.IsOpen)
              {
                  string received;
                  testSerial.DiscardInBuffer();
                  try
                  {
                      //testSerial.DataReceived += new SerialDataReceivedEventHandler(testSerialPort_DataReceived);
  
                      testSerial.Write(testMessage);
                      System.Threading.Thread.Sleep(2000);
  
                      received = testSerial.ReadExisting();  //EITHER I USE THIS OR EVENT HANDLER, NOT BOTH
                  }
                  catch (TimeoutException e)
                  {
                      testSerial.Close();
                      continue;
                  }
  
                 if (received.Length &gt; 0)
                  {
                      MessageReceived(received);
                  }
                  testSerial.Close();
              }
         } 
   }
  
  
  
   private void testSerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
      {
          string received = testSerial.ReadExisting();
          int y = received.IndexOf("\r");
          while (y == -1)
          {
              received = received + testSerial.ReadExisting();
              y = received.IndexOf("\r");
          }
  
          if (testSerial.IsOpen)
          {
              testSerial.Close();
          }
  
      }
  </code></pre>
  
  <p>i'm wondering, if i absolutely have to use datahandler, how do i keep the serial port open long enough to read from it, but close the serialport before the next port needs to be opened?</p>
  
  <p>see, the first method gets called a few times, and it iterates through a foreach loop, trying a message on a few ports, then trying to read a response.  so, at some point i have to close the ports, or else the next time it goes through it, it doesn't work properly because the port is still open</p>
  
  <p>HERE'S MY UPDATED CODE (still not working):</p>
  
  <pre><code> private void CheckPorts(string testMessage, int baudRate)
      {
  
          foreach (string s in SerialPort.GetPortNames())
          {
              var interval = 3000; // ms 
              var timer = new System.Timers.Timer(interval);
              timer.Elapsed += (o, e) =&gt;
              {
                  timer.Enabled = false;
  
                  if (testSerial.IsOpen)
                      testSerial.Close();  // may not be necessary with Dispose? 
  
                  testSerial.Dispose();
                  timer.Dispose();
              };
  
              portNumber = Int32.Parse(s.Remove(0, 3));
              testSerial = new SerialPort(s, baudRate, Parity.None, 8, StopBits.One);
              testSerial.ReadTimeout = 2000;
              testSerial.WriteTimeout = 2000;
              if (testSerial.IsOpen)
              {
                  testSerial.Close();
              }
  
              testSerial.Open();
              timer.Enabled = true; 
  
              if (testSerial.IsOpen)
              {
                  string received;
                  //testSerial.DiscardInBuffer();
                  //autoEvent = new AutoResetEvent(false);
                  try
                  {
                     // testSerial.DataReceived += new SerialDataReceivedEventHandler(testSerialPort_DataReceived);
  
                    // autoEvent.Reset();
                      lblPortNum.Content = s;
                      lblPortNum.Refresh();
  
                      testSerial.Write(testMessage);
                      //System.Threading.Thread.Sleep(2000);
  
                      //testSerial.NewLine = "\r\n";
                      byte[] rBuff = new byte[2];
                      int rCnt = testSerial.Read(rBuff, 0, 2);
                      System.Text.Encoding enc = System.Text.Encoding.ASCII;
                      received = enc.GetString(rBuff);
  
  
  
                       //received = testSerial.ReadLine();
                  }
                  catch (TimeoutException e)
                  {
                      testSerial.Close();
                      continue;
                  }
  
                 if (received.Length &gt; 0)
                 {
                      MessageReceived(received, Int16.Parse(s.Remove(0, 3)));
                  }
                  /*
                  if (autoEvent.WaitOne(2000))
                  {
                      // the port responded 
                     // testSerial.Close();
                      autoEvent.Dispose();
                      lblPortNum.Content = "HEY I RESPONDED";
                  }
                  else
                  {
                      testSerial.Close();
                      autoEvent.Dispose();
                      continue;
                      // port did not respond within 2 seconds 
                  }*/
                //testSerial.Close();
              }
          } 
       }
  </code></pre>
  
  <p>UPDATED AGAIN (still not working properly)</p>
  
  <pre><code>private void CheckPorts(string testMessage, int baudRate)
      {
  
          foreach (string s in SerialPort.GetPortNames())
          {
              portNumber = Int32.Parse(s.Remove(0, 3));
  
              // MUST BE LOCAL 
              var serialOneOfMany = new SerialPort(s, baudRate, Parity.None, 8, StopBits.One);
              serialOneOfMany.ReadTimeout = 2000;
              serialOneOfMany.WriteTimeout = 2000;
              if (serialOneOfMany.IsOpen)
              {
                  serialOneOfMany.Close();
              }
  
              // timer must be defined _after_ serialOneOfMany 
              var interval = 3000; // ms  
              var timer = new System.Timers.Timer(interval);
              timer.Elapsed += (o, e) =&gt;
              {
                  timer.Enabled = false;
  
                  if (serialOneOfMany.IsOpen)
                      serialOneOfMany.Close();  // may not be necessary with Dispose?  
  
                  serialOneOfMany.Dispose();
                  timer.Dispose();
              };
  
              if (serialOneOfMany.IsOpen)
              {
                  string received;
  
                  try
                  {
                      lblPortNum.Content = s;
                      lblPortNum.Refresh();
  
                      serialOneOfMany.Write(testMessage);
                      byte[] rBuff = new byte[2];
                      int rCnt = serialOneOfMany.Read(rBuff, 0, 2);
                      System.Text.Encoding enc = System.Text.Encoding.ASCII;
                      received = enc.GetString(rBuff);
  
                  }
                  catch (TimeoutException e)
                  {
                      serialOneOfMany.Close();
                      continue;
                  }
  
                  if (received.Length &gt; 0)
                  {
                      CheckIfTheMessageMatches(received, Int16.Parse(s.Remove(0, 3)));
                  }
  
              }
          } 
  
      }
  </code></pre>
  
  <p>so with this update, it just blows through the code, i can step through the code line by line, but it doesn't stop for 3 seconds at all.  if i run it without any debugging breaks, it just goes through it i a fraction of a second</p>
  
  <p>UPDATE 10-25-11</p>
  
  <pre><code> private void CheckPorts(string testMessage, int baudRate)
      {
          foreach (string s in SerialPort.GetPortNames())
          {
              string received = "";
              testSerial = new SerialPort(s,baudRate, Parity.None, 8, StopBits.One);
  
              lblStatus.Content = "Scanning...";
              lblStatus.Refresh();
  
              if (testSerial.IsOpen)
              {
                  testSerial.Close();
              }
              else
              {
                  testSerial.Open();
              }
  
              if (testSerial.IsOpen)
              {
                  try
                  {
                      testSerial.NewLine = "\r";
                      lblPortNum.Content = s;
                      lblPortNum.Refresh();
                      testSerial.WriteTimeout= 500;
                      testSerial.ReadTimeout = 1000;
                      testSerial.WriteLine(testMessage);
  
                      System.Threading.Thread.Sleep(500);
  
                      /*THIS DOESN'T WORK
                      byte[] buffer = new byte[testSerial.BytesToRead];
                      int rCnt = testSerial.Read(buffer, 0, buffer.Length);
                      received = enc.GetString(buffer);*/
  
                      //received = Convert.ToString(testSerial.BaseStream.Read(buffer, 0, (int)buffer.Length));
  
  
                      received =  testSerial.ReadLine();
  
  
                     int y = received.IndexOf("\r");
                     while (y == -1)
                     {
                         received = received + testSerial.ReadExisting();
                         y = received.Length;
                     }
  
                     if (lblInfo.Dispatcher.Thread == Thread.CurrentThread)
                     {
                         CheckIfTheMessageMatches(received, s);
                         received = received + lblInfo.Content;
                         lblInfo.Content = received;
                     }
                     else
                     {
                         lblInfo.Dispatcher.Invoke(DispatcherPriority.Normal, new ThreadCheck(threadCheck), received);
                     }
                     if (testSerial.IsOpen)
                     {
                         testSerial.Close();
                     }
  
                      /*I USE THIS WITH THE sPort.Read() METHOD
                      while (rCnt &gt; 0)
                      {
                          if (lblInfo.Dispatcher.Thread == Thread.CurrentThread)
                          {
                              CheckIfTheMessageMatches(received, s);
                              rCnt = 0;
                              received = received + lblInfo.Content;
                              lblInfo.Content = received;                                
                          }
  
                          else
                          {
                              lblInfo.Dispatcher.Invoke(DispatcherPriority.Normal, new ThreadCheck(threadCheck), received);
                          }
                      }
                       */
  
                     if (testSerial.IsOpen)
                     {
                         testSerial.Close();
                     }
  
                  }
                  catch (TimeoutException e)
                  {
                      testSerial.Close();
                      continue;
                  }
                  received = null;
              }
          } 
  
          lblStatus.Content = "Finished Scanning.";
          lblPortNum.Content = "";
      }
  </code></pre>
  
  <p>UPDATED CODE
  here's some new code, still not working, dataeventhandler not even called once.  i know it's getting messages because i have another program that works with the serial devices</p>
  
  <pre><code>private void CheckPorts(string testMessage, int baudRate)
      {
          foreach (string s in SerialPort.GetPortNames())
          {
              var serialOneOfMany = new SerialPort(s, baudRate, Parity.None, 8, StopBits.One);
              serialOneOfMany.ReadTimeout = 700;
              serialOneOfMany.WriteTimeout = 100;
  
              var interval = 500; // ms
              var timer = new System.Timers.Timer(interval);
              timer.Elapsed += (o, e) =&gt;
              {
                  timer.Enabled = false;
  
                  if (serialOneOfMany.IsOpen)
                      serialOneOfMany.Close();  // may not be necessary with Dispose?
  
                  serialOneOfMany.Dispose();
                  timer.Dispose();
              };
              timer.Enabled = true;
  
              lblStatus.Content = "Scanning...";
              lblStatus.Refresh();
  
              if (serialOneOfMany.IsOpen)
              {
                  serialOneOfMany.Close();
              }
              else
              {
                  serialOneOfMany.Open();
              }
  
              if (serialOneOfMany.IsOpen)
              {
                  string received;
  
                  try
                  {
                      lblPortNum.Content = s;
                      lblPortNum.Refresh();
  
                      serialOneOfMany.WriteLine(testMessage);
                      System.Threading.Thread.Sleep(400);
                      serialOneOfMany.DataReceived += new SerialDataReceivedEventHandler(testSerialPort_DataReceived);
  
                  }
                  catch (TimeoutException e)
                  {
                      serialOneOfMany.Close();
                      continue;
                  }
              }
          } 
  
          lblStatus.Content = "Finished Scanning.";
          lblPortNum.Content = "";
      }
  
      private void testSerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
      {
          SerialPort receivingSerial = sender as SerialPort;
          string received = receivingSerial.ReadExisting();
          int y = received.IndexOf("\r");
          while (y == -1)
          {
              received = received + receivingSerial.ReadExisting();
              y = received.IndexOf("\r");
          }
  
          if (lblInfo.Dispatcher.Thread == Thread.CurrentThread)
          {
              string name = receivingSerial.PortName;
              received = received + lblInfo.Content;
              lblInfo.Content = received;
              CheckIfTheMessageMatches(received, name);
          }
          else
          {
              lblInfo.Dispatcher.Invoke(DispatcherPriority.Normal, new ThreadCheck(threadCheck), received);
          } 
          if (receivingSerial.IsOpen)
          {
              receivingSerial.Close();
          }
  
      }
  </code></pre>