title: C# - How to hand off which thread reads from serial port?
body: <h1>Background</h1>
  
  <p>A customer asked me to find out why their C# application (we'll call it XXX, delivered by a consultant who has fled the scene) is so flaky, and fix it. The application controls a measurement device over a serial connection. Sometimes the device delivers continuous readings (which are displayed on screen), and sometimes the app needs to stop continuous measurements and go into command-response mode.</p>
  
  <h1>How <em>NOT</em> to do it</h1>
  
  <p>For continuous measurements, XXX uses <code>System.Timers.Timer</code> for background processing of serial input. When the timer fires, C# runs the timer's <code>ElapsedEventHandler</code> using some thread from its pool. XXX's event handler uses a blocking <code>commPort.ReadLine()</code> with a several second timeout, then calls back to a delegate when a useful measurement arrives on the serial port. This portion works fine, however...</p>
  
  <p>When its time to stop realtime measurements and command the device to do something different, the application tries to suspend background processing from the GUI thread by setting the timer's <code>Enabled = false</code>. Of course, that just sets a flag preventing further events, and a background thread already waiting for serial input continues waiting. The GUI thread then sends a command to the device, and tries to read the reply – but the reply is received by the background thread. Now the background thread becomes confused as its not the expected measurement. The GUI thread meanwhile becomes confused as it didn't receive the command reply expected. Now we know why XXX is so flaky.</p>
  
  <h1>Possible Method 1</h1>
  
  <p>In another similar application, I used a <code>System.ComponentModel.BackgroundWorker</code> thread for free-running measurements. To suspend background processing I did two things in the GUI thread:</p>
  
  <ol>
  <li>call the <code>CancelAsync</code> method on the thread, and</li>
  <li>call <code>commPort.DiscardInBuffer()</code>, which causes a pending (blocked, waiting) comport read in the background thread to throw a <code>System.IO.IOException "The I/O operation has been aborted because of either a thread exit or an application request.\r\n"</code>. </li>
  </ol>
  
  <p>In the background thread I catch this exception and clean up promptly, and all works as intended. Unfortunately <code>DiscardInBuffer</code> provoking the exception in another thread's blocking read is not documented behavior anywhere I can find, and I hate relying on undocumented behavior. It works because internally <code>DiscardInBuffer</code> calls the Win32 API PurgeComm, which interrupts the blocking read (documented behavior).</p>
  
  <h1>Possible Method 2</h1>
  
  <p>Directly use the <code>BaseClass Stream.ReadAsync</code> method, with a monitor cancellation token, using a supported way of interrupting the background IO. </p>
  
  <p>Because the number of characters to be received is variable (terminated by a newline), and no <code>ReadAsyncLine</code> method exists in the framework, I don't know if this is possible. I could process each character individually but would take a performance hit (might not work on slow machines, unless of course the line-termination bit is already implemented in C# within the framework).</p>
  
  <h1>Possible Method 3</h1>
  
  <p>Create a lock "I've got the serial port". Nobody reads, writes, or discards input from the port unless they have the lock (including repeating the blocking read in background thread). Chop the timeout values in the background thread to 1/4 second for acceptable GUI responsiveness without too much overhead.</p>
  
  <h1>Question</h1>
  
  <p>Does anybody have a proven solution to deal with this problem?
  How can one cleanly stop background processing of the serial port?
  I've googled and read dozens of articles bemoaning the C# <code>SerialPort</code> class, but haven't found a good solution.</p>
  
  <p>Thanks in advance!</p>