SerialPort UnauthorizedAccessException

Sometimes some of my integration tests do not work with the message above. I use the code below to prepare the port.

for(int i = 0; i < 5; i++) { try { port.Open(); if (port.IsOpen) break; } catch (Exception e) { try { port.Close(); } catch (Exception) {} Thread.Sleep(300); } } 

My assumption is that since it cannot be the current thread blocking the port (because it will try to close it), it must be another thread or process that died without being cleaned properly (one of the other tests is nothing else does not access this port). Is there a way to reset the state of SerialPort so that a new thread / process can access it again?

Thanks,

Richard

+7
source share
4 answers

This is a flaw in the SerialPort class; it uses an internal auxiliary thread to wait for events on the port. The event source is DataReceived, PinChanged, and ErrorReceived. The disadvantage is the implementation of the Close () method; it does not wait for the completion of this auxiliary stream. It takes time, the exact time is not predictable, and can be many seconds when the machine is especially busy. The physical port does not close until this happens, opening the port before the thread exits the bombs with the exception of the "port already in use" exception. The one you get. Thus, sleeping for 300 ms is not enough.

This is usually not a problem; serial ports are not compatible devices. Closing the serial port rather than exiting your program is dangerous; another process might steal the port. This exception is also given to you when you try to open it again. A common practice is to open the port at application startup and not close it until it is completed.

+11
source

I regularly check that the port is closed just before creating an instance of the serial port. This helps if you stop code debugging without closing the serial port. You should also wait 250 ms after opening or closing the port, before continuing with your code.

 try { if ((m_SerialPort != null)) { if (m_SerialPort.IsOpen) { m_SerialPort.Close(); } } m_SerialPort = new SerialPort(portName, dataRate, parity, databits, stopBits.One); m_SerialPort.Open(); if (!m_SerialPort.IsOpen) { MessageBox.Show(string.Concat(portName, " failed to open")); } } catch (Exception ex) { MessageBox.Show(ex.Message); } 
+4
source

I do not see where you are closing the port.

The problem for me is not here (even if you need to redo the code a bit), but you are probably calling port.Open(); when the port is still open

From MSDN

Only one open connection can exist for each SerialPort object.

(I can’t say why, because I don’t have enough information). Remember also that the close method takes some time to actually close the port. In fact, you should block the main thread until the port is closed (possibly using Thread.Join)

From MSDN

The best practice for any application is to wait some time after calling the Close method before trying to call the Open method, since the port cannot be closed immediately.

for more information

http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.open.aspx

+2
source

GC.SuppressFinalize and GC.ReRegisterForFinalize should be called passing the property of the SerialPort BaseStream as a parameter, not just the SerialPort instance.

0
source

All Articles