-1

I have a private function that creates a new serial port and opens it. From time to time, I get the "Safe handle has been closed" exception, that terminates the application. Now, I've been reading a few optional fixes and would like to know from your experience, what may be the real problem in my code. 1) Need to define the _serialPort variable outside of the scope of this private function. 2) The serial port's readTimeout property should not be infinite. 3) The using statement above disposes my portName variable.

SerialPort _serialPort;
string[] devices = 
ConfigurationManager.AppSettings["GasAnalyzerDeviceName"].Split(',');
string portName;
using (var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PnPEntity"))
{
    portName = (from p in searcher.Get().Cast<ManagementBaseObject>()
                                let c = "" + p["Caption"]
                                where c != null
                                where devices.Any(d => c.Contains(d.Trim()))
                                from pn in SerialPort.GetPortNames()
                                where c.Contains(pn)
                                select pn).FirstOrDefault();

}
                if (portName == null)
                    portName = ConfigurationManager.AppSettings["GasAnalyzerPortName"];

                if (portName == null)
                    throw new Exception("Gas port not found");

                // Create a new SerialPort object with default settings.
                _serialPort = new SerialPort();

                // Set Serial port properties
                _serialPort.PortName = portName;
                _serialPort.BaudRate = 115200;
                _serialPort.DataBits = 8;
                _serialPort.Parity = Parity.None;
                _serialPort.StopBits = StopBits.One;
                _serialPort.Handshake = Handshake.None;
                _serialPort.ReadTimeout = Timeout.Infinite;//1200;
                _serialPort.WriteTimeout = 1200;

Thanks!

NettaD
  • 13
  • 1
  • 7
  • 2
    The real problem with your code is that it's not posted in your question. – Guy Sep 10 '17 at 09:05
  • @Guy, it is now, had a problem with that. Thanks. – NettaD Sep 10 '17 at 09:08
  • What line is throwing the exception? – mjwills Sep 10 '17 at 09:20
  • Please include the **entire** class. What happens if you change `_serialPort = new SerialPort();` to `var _serialPort = new SerialPort();`? – mjwills Sep 10 '17 at 10:35
  • @mjwills, this type of exception doesn't have a stack trace. What is changing type to var supposed to do? – NettaD Sep 10 '17 at 11:40
  • @NettaD I am concerned about whether you have a race condition due to two threads sharing the same `_serialPort`. The `_` at the start makes me think the variable is declared **outside** the function. Adding `var` would force it to be declared **inside** the function. As I mentioned earlier it would be awesome if you included the **entire** class in your post. – mjwills Sep 10 '17 at 11:56
  • @mjwills, the class is really (!) big. I actually copied this variable from another class, where it was outside of the function (that's why the _ si there), and I've put the declaration inside my function, maybe that's my mistake. – NettaD Sep 10 '17 at 12:21

1 Answers1

0

I think you can discard options 2) and 3).

Number one is a possible candidate, but there is not enough code to be sure: If there are no other references to your SerialPort it becomes a candidate for garbage collection. Once it is garbage collected, any attempt to access it will result in an exception, tough I would expect a NullReferenceException.

There can be another cause: if your serial port is emulated over e.g. a USB device, and that device gets removed while your application is running, the underlying connection will be disposed. When you try to use the SerialPort in your application after that has happened, you will get the 'safe handle has been closed' exception.

Johan Donne
  • 3,104
  • 14
  • 21
  • Thanks, the device doesn't get removed, so it's probably thw first solution. Since it doesn't happen all the time, I'll just have to wait and check if the problem returns with the new fix. Thanks! – NettaD Sep 10 '17 at 12:09