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!
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 aNullReferenceException
.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.