Home Dashboard Directory Help

SerialPort.Close() hangs the application by Vince Noga


 as By Design Help for as By Design

Sign in
to vote
Type: Bug
ID: 202137
Opened: 9/13/2006 12:11:37 PM
Access Restriction: Public
User(s) can reproduce this bug


Calling SerialPort.Close() on an open serial port hangs the application.
Sign in to post a comment.
Posted by markoni on 8/1/2009 at 1:56 AM
Change "this.Invoke" in to "this.BeginInvoke".
Posted by Microsoft on 5/11/2007 at 5:09 PM
Thanks Vnoga and Nobugz, and we apologize for failing to post a workaround earlier!

As described in the blog Nobugz linked to, there is deadlock between the UI thread and the threadpool threads. So the workaround you described -- closing the port on another thread -- will work, but you can also replace Control.Invoke calls with Control.InvokeLater calls. This workaround is a less invasive and a good practice generally.

Posted by nobugz on 5/11/2007 at 2:19 PM
Kim Hamilton has posted a diagnostic and a workaround for this problem on this blog post:

Posted by Vince Noga on 9/19/2006 at 5:45 AM
Closing the port in another thread is the way to go.
Posted by Vince Noga on 9/18/2006 at 12:24 PM
Well, from futher testing, the workaround I posted today (09/18/2006) doesn't work 100% of the time. It made the hang less likely, but it can still happen.
Sign in to post a workaround.
Posted by Unregistered User on 5/7/2007 at 3:42 PM
I'm confused. The Issue Status says "Closed (By Design)". If SerialPort->Close() is "Designed" to work this way then it should be renamed to:


It would have saved me days of debugging if it were named more appropiately.

Seriously, I know MS doesn't want to support "Legacy" serial devices (or anything not PnP) and wishes these devices would just go away, but there are a gazillion serial port devices still out there and manufacturers are still making new Serial Port based products which programmers still have to make apps for.

Unless MS can talk H/W Manufacturers out of making Serial devices, you gotta help us out.

So how do we get this Issue reopened?
Posted by Vince Noga on 9/18/2006 at 5:15 AM
Another (very lame) workaround is to update the user-interface (UI) in a different thread. It should not be this difficult to collect data from a serial port and display it in the UI.

*** WARNING ***
This simple example is just that, a simple example. It does not prevent data loss from the serial port to the UI.

        private AutoResetEvent are = new AutoResetEvent(false);
        private bool portOpen = false;
        private string serialData = "";

        private void button1_Click(object sender, EventArgs e)
            if (!serialPort1.IsOpen)
                    serialPort1.PortName = "COM1";
                    serialPort1.BaudRate = 9600;
                    serialPort1.DataBits = 7;
                    serialPort1.Parity = System.IO.Ports.Parity.Even;
                    serialPort1.StopBits = System.IO.Ports.StopBits.One;
                    portOpen = true;
                    Thread t = new Thread(new ThreadStart(MonitorPort));
                    t.IsBackground = true;
                catch (Exception ex)
                    MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK,

        private void button2_Click(object sender, EventArgs e)
            if (serialPort1.IsOpen)
                //Tell MonitorPort() to stop updating the UI
                portOpen = false;

                //Wait for MonitorPort() to signal that it's done


        //Declare a method signature that can be Invoked
//        private delegate void UIUpdater(string s);
        private delegate void UIUpdater();

        //A method that has the same signature as UIUpdater()
//        private void UIUpdate(string s)
        private void UIUpdate()
            textBox1.Text = serialData;

        private void MonitorPort()
                //All this thread does is write the serial data to the UI.
                //This simple example is not written to prevent data loss!
                while (portOpen)
                    this.Invoke(new UIUpdater(UIUpdate));
                //Signal that the thread is terminating

        private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
            //If continuous data from the device, application can hang when
         //SerialPort.Close() is called.
            //this.Invoke(new UIUpdater(UIUpdate),
            // new object[] { serialPort1.ReadExisting() });

            //Save the data to an object where .Invoke() is not required.
            //This simple example is not written to prevent data loss!
            serialData = serialPort1.ReadExisting();
Posted by Personal Information Withheld on 9/15/2006 at 7:32 AM
A (very lame) workaround is to do the close in a new thread. I haven't tested trying to reopen the port and I'm not sure that it would be a good thing to do!