title: C# Winform freezing on SerialPort.Close
body: <p>I have a winform program that does some asynchronous IO on a <code>SerialPort</code>.  However, I'm periodically running into an issue with the program freezing on the SerialPort.Close() call, seemingly at random.</p>
  
  <p>I think it's a thread safety issue, but I'm not sure how to fix it if it is.  I tried adding/removing the async DataReceived handler with the port open/close functions and discarding the in and out buffers on the port, but it doesn't seem to do anything.  I think the important <code>SerialPort</code> code is below:</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.IO.Ports;
  
  public class SerialComm
  {
    private object locker = new object();
  
    private SerialPort port;
    private List&lt;byte&gt; receivedBytes;
  
    public SerialComm(string portName)
    {
      port = new SerialPort(portName);
      port.BaudRate = 57600;
      port.Parity = Parity.None;
      port.DataBits = 8;
      port.StopBits = StopBits.One;
  
      receivedBytes = new List&lt;byte&gt;();
    }
  
    public void OpenPort()
    {
      if(port!=null &amp;&amp; !port.IsOpen){
        lock(locker){
          receivedBytes.Clear();
        }
  
        port.DataReceived += port_DataReceived;
        port.Open();
      }
    }
  
    public void ClosePort()
    {
      if(port!=null &amp;&amp; port.IsOpen){
        port.DataReceived -= port_DataReceived;
        while(!(port.BytesToRead==0 &amp;&amp; port.BytesToWrite==0)){
          port.DiscardInBuffer();
          port.DiscardOutBuffer();
        }
        port.Close();
      }
    }
  
    private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
      try{
        byte[] buffer = new byte[port.BytesToRead];
        int rcvdBytes = port.Read(buffer, 0, buffer.Length);
  
        lock(locker){
          receivedBytes.AddRange(buffer);
        }
  
        //Do the more interesting handling of the receivedBytes list here.
  
      } catch (Exception ex) {
        System.Diagnostics.Debug.WriteLine(ex.ToString());
        //put other, more interesting error handling here.
      }
    }
  }
  </code></pre>
  
  <p><strong>UPDATE</strong></p>
  
  <p>Thanks to @Afrin's answer pointing out the deadlock condition with the UI thread (<a href="http://blogs.msdn.com/b/bclteam/archive/2006/10/10/top-5-serialport-tips-_5b00_kim-hamilton_5d00_.aspx" rel="noreferrer">This blog post</a> does a good job describing it, and gives several other good tips), I made a simple change, and haven't been able to reproduce the error yet!</p>
  
  <pre><code>private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
  {
    try{
      byte[] buffer = new byte[port.BytesToRead];
      int rcvdBytes = port.Read(buffer, 0, buffer.Length);
  
      lock(locker){
        receivedBytes.AddRange(buffer);
      }
  
      ThreadPool.QueueUserWorkItem(handleReceivedBytes);
  
    } catch (Exception ex) {
      System.Diagnostics.Debug.WriteLine(ex.ToString());
      //put other, more interesting error handling here.
    }
  }
  
  private void handleReceivedBytes(object state)
  {
    //Do the more interesting handling of the receivedBytes list here.
  }
  </code></pre>