I write software using c# in VS2017. My software runs on windows 10,64bits pc, and it will communicate with another device using rs422, which will convert to a USB to connect with my pc. The device will send messages to me every 0.5 seconds, and I can send messages to the device via rs422 in random order.
So I use SerialPort class to do the communication work.
In my process, I create several threads to send messages to the device in random order via the same SerialPort class instance.
Most times it works well. But in some cases, maybe because the hardware of the rs422 chip or wire isn’t stable, my app can’t receive any message from the device, and at the same time, only one thread can send messages using SerialPort.Write Method of SerialPort class instance. And when other threads try to access the instance using Write method of the class), it will raise an UnauthorizedAccessException, the Exception is as below:
*2021-01-03 17:59:46| Error| UartSender.DoMonitor=>Monitor=>RunInternal=>|Uart Send Exception
Access to the port is denied.
An exception of type System.UnauthorizedAccessException occurred and was caught.
01/03/2021 17:59:46
Type: System.UnauthorizedAccessException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Message: Access to the port is denied.
Source: System
HelpLink:
TargetSite : Void WinIOError(Int32, System.String)
HResult : -2147024891
StackTrace : at System.IO.Ports.InternalResources.WinIOError(Int32 errorCode, String str)
at System.IO.Ports.SerialStream.BeginWriteCore(Byte[] array, Int32 offset, Int32 numBytes, AsyncCallback userCallback, Object stateObject)
at System.IO.Ports.SerialStream.Write(Byte[] array, Int32 offset, Int32 count, Int32 timeout)
at System.IO.Ports.SerialPort.Write(Byte[] buffer, Int32 offset, Int32 count)
at XXXXXX() in D:\XXXXX\UartSender.cs:line 120
AdditionalInfo
MachineName : DESKTOP-SHOR3RC
TimeStamp : 1/3/2021 9:59:46 AM
FullName : XXX, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
AppDomainName : XXXXX.exe
ThreadIdentity :
WindowsIdentity : DESKTOP-SHOR3RC\ML_Server_HP*
If this happens, another thread will try to reconnect the serial port via close the serial port and open it again. Then when close or open the serial port, exceptions occur:
Close exception information is as below:
*2021-01-05 16:27:37| Error| XXXXX.CloseSerPort=>SerialPortInit=>DoMonitor=>|Exception
Access to the port is denied.
An exception of type System.UnauthorizedAccessException occurred and was caught.
01/05/2021 16:27:37
Type: System.UnauthorizedAccessException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Message: Access to the port is denied.
Source: System
HelpLink:
TargetSite : Void WinIOError(Int32, System.String)
HResult : -2147024891
StackTrace : at System.IO.Ports.InternalResources.WinIOError(Int32 errorCode, String str)
at System.IO.Ports.SerialStream.Dispose(Boolean disposing)
at System.IO.Stream.Close()
at System.IO.Ports.SerialPort.Dispose(Boolean disposing)
at System.IO.Ports.SerialPort.Close()
at XXXXX.CloseSerPort() in D:\XXXXX.cs:line 199
AdditionalInfo
MachineName : DESKTOP-KBNRM8A
TimeStamp : 1/5/2021 8:27:37 AM
FullName : XXXX, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
AppDomainName : XXXX.exe
ThreadIdentity :
WindowsIdentity : XXXX\XXXXX*
Open exception information is as below:
*2021-01-03 17:59:49| Error| XXXXXXX.SerialPortInit=>DoMonitor=>Monitor=>|Exception
Access to the port 'COM24' is denied.
An exception of type System.UnauthorizedAccessException occurred and was caught.
01/03/2021 17:59:49
Type: System.UnauthorizedAccessException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Message: Access to the port 'COM24' is denied.
Source: System
HelpLink:
TargetSite : Void WinIOError(Int32, System.String)
HResult : -2147024891
StackTrace : at System.IO.Ports.InternalResources.WinIOError(Int32 errorCode, String str)
at System.IO.Ports.SerialStream..ctor(String portName, Int32 baudRate, Parity parity, Int32 dataBits, StopBits stopBits, Int32 readTimeout, Int32 writeTimeout, Handshake handshake, Boolean dtrEnable, Boolean rtsEnable, Boolean discardNull, Byte parityReplace)
at System.IO.Ports.SerialPort.Open()
at XXXX.SerialPortInit(String portName) in D:\XXXXX.cs:line 249
AdditionalInfo
MachineName : DESKTOP-SHOR3RC
TimeStamp : 1/3/2021 9:59:49 AM
FullName : XXXX, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
AppDomainName : XXXX.exe
ThreadIdentity :
WindowsIdentity : XXXXXCX*
And from that on, my app can’t connect with the serial port.
Then I restart (close and open) my app again, when I open the serial port, the same exception as above occurs again.
Then the only way to solve it is to pull out the rs422 hardware and plugin it again.
So from the above process, I guess when the problem happens for the first time, the serial port instance and its relative resource seem to have been occupied exclusively by one thread, and other threads haven’t authorized to access it. And what is worse, even if the thread and its process has been destroyed, all the resource still hasn’t been released.
So my questions are:
(1) What methods or tools can give me clue to see what happens to it?
(2) What kinds of problems will result in the serial port and its resource will be occupied exclusively by one thread?
(3) How can I release the resource to reconnect the serial port?
(4) Can C# or windows provide me some APIs to monitor and solve the problem?