10

I have an app where I read from the serialport, everything goes fine, until I close the app. When I click on the [X] the app simply hangs, the UI: unresponsive.

I read from the port in the DataReceived event handler, and I close the port when FormClosed happens:

    private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
    {
        mySerialPort.Close();
    }
H H
  • 263,252
  • 30
  • 330
  • 514
gdario
  • 231
  • 2
  • 3
  • 5

5 Answers5

10

It's not a bug.

The only reason it would hang when you close it is because in the event handler of your SerialPort object, you're synchronizing a call with the main thread (typically by calling invoke). SerialPort's close method waits for its EventLoopRunner thread which fires DataReceived/Error/PinChanged events to terminate, but since your own code in the event is also waiting for main thread to respond, you run into a dead lock situation.

The reason the bug report was closed 'as designed' is because the 'bug' is in your own code.

Zach Saw
  • 4,308
  • 3
  • 33
  • 49
7

Serial Port hangs while closing

This is a known issue with the SerialPort class and described in this Product Feedback article as well as several threads in these forums. You may notice the "closed by design" dismissal.

SwDevMan81
  • 48,814
  • 22
  • 151
  • 184
  • 1
    +1, this ties in with the OP's previous question. But for a good SO answer you could have posted short summary **here**. Suppose that that page moves? – H H Nov 08 '09 at 13:47
  • 2
    UNBELIEVABLE!!! this is a known bug in the framework which as closed by MS as "works as designed!!!" +1 for the reference – mfeingold Nov 08 '09 at 14:26
  • LOL. See my answer below. There's a serious serial port code bug in .NET framework but this is *NOT* it. – Zach Saw Sep 29 '11 at 07:42
7

If your application is calling Invoke to process recevied data try calling BeginInvoke instead.

Instead of:

this.Invoke(d, new object[] { s, tb });

use:

this.BeginInvoke(d, new object[] { s, tb });
Mark Dietel
  • 271
  • 3
  • 3
2

Simplest solution if you only want to close the port when the app closes, is to just not bother to Close() the port. The port will still get closed anyway when the app disposes of the serial port. The port will be available to be opened again by your app when it restarts, or by other apps that may wish to use the port.

ceptimus
  • 21
  • 1
  • It will hang on the dispose as well... when the dispose closes it so yous till have to use BeginInvoke. Of course it doesn't matter if you close the application out.. however it does matter if you open and close multiple serial ports without closing your app. – cb88 Jul 23 '15 at 17:40
1

this work very good :

 private void Form_FormClosing(object sender, FormClosingEventArgs e)
    {

        if (_serialPort.IsOpen)
        {
            e.Cancel = true; //cancel the fom closing
            Thread CloseDown = new Thread(new ThreadStart(CloseSerialOnExit)); //close port in new thread to avoid hang
            CloseDown.Start(); //close port in new thread to avoid hang
        }
    }

 private void CloseSerialOnExit()
    {
        try
        {
            _serialPort.Close(); //close the serial port
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message); //catch any serial port closing error messages
        }
        this.Invoke(new EventHandler(NowClose)); //now close back in the main thread
    }

    private void NowClose(object sender, EventArgs e)
    {
        this.Close(); //now close the form
    }
payam purchi
  • 226
  • 1
  • 11