In SerialPort, Access Denied when calling Close, but not Dispose

1

UPDATE 1

I found out that if I reverse the order of my close/dispose then I get the error from dispose instead of close... so probably disposable protection means the method is only invoked once.

I've been able to replicate the error on my device by creating a short to ground on one of the Data Lines. I'm using an FT230x on my device and found that if I short the Reset Pin then communication can resume, however now I am getting a different exception from my application as soon as I do this. So technically my application will now reconnect on a restart, which is an improvement where as before I had to physically unplug and replug my device. New Exception Below:

System.ObjectDisposedException
  HResult=0x80131622
  Message=Safe handle has been closed
  Source=mscorlib
  StackTrace:
   at System.Runtime.InteropServices.SafeHandle.DangerousAddRef(Boolean& success)
   at System.StubHelpers.StubHelpers.SafeHandleAddRef(SafeHandle pHandle, Boolean& success)
   at Microsoft.Win32.UnsafeNativeMethods.GetOverlappedResult(SafeFileHandle hFile, NativeOverlapped* lpOverlapped, Int32& lpNumberOfBytesTransferred, Boolean bWait)
   at System.IO.Ports.SerialStream.EventLoopRunner.WaitForCommEvent()
   at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()

New weirdness is that the callstack doesn't contain any of my code and Visual Studio isn't allowing me to trace it back to my code.

ORIGINAL POST

I have a device that is giving me an IOException on a SerialPort.Write, and then when I attempt to close the port I get UnauthorizedAccessException. Following that I can dispose the serialport without exception, but attempts to re-open the port result in UnauthorizedAccessException. My real confusion comes in when I keep reading that Dispose and Close are supposed to do the exact same thing. Is there a way I can recover from this without restarting the program (or in some cases the computer)?

In my project, I manage multiple devices that either use the same Com Port or use a unique com port. So I have a manager that manages my devices, finds their ports, and creates a port manager for those devices. Sometimes devices disconnect and when that happens I close and dispose the com port and the com port manager. Below is my code:

private void DisposeComPort()
{
    if (ComPort != null)
    {
        string message = "Disposing Com Port.";
        try
        {
            ComPort.DataReceived -= ComPort_DataReceived;
            ComPort.ErrorReceived -= ComPort_ErrorReceived;
            message += " Com Port Events Unsubscribed.";

        }
        catch (Exception ex)
        {
            HandleException(this, ex, "Exception attempting to remove Handlers for on " + this.ToString() + ".");

        }
        try
        {
            if (ComPort.IsOpen)
            {
                ComPort.Close(); message += " Com Port Closed.";
            }
        } catch(Exception ex)
        {
            HandleException(this, ex, "Exception attempting to close on " + this.ToString() + ".");
        }
        try
        {
            ComPort.Dispose(); message += " Com Port Disposed.";
        } catch (Exception ex)
        {
            HandleException(this, ex, "Exception attempting to Dispose Com Port on " + this.ToString() + ".");
        }
        ComPort = null;
        LogMessage(this, message);
    }
}

I have a single device that is every couple of days giving me "System.IO.IOException: A device attached to the system is not functioning" when I attempt ComPort.Write(). When this happens I attempt to dispose my com port. Under Normal circumstances I would be able to close the port and reopen it, however in this case my code fails to close and succeeds to dispose, however when my device manager attempts to re-open the com port I continue to get UnauthorizedAccessException. Below is my exception log.

11:26:35.862, Exception Sending Com Packet to Device 34 on ModbusPortManager Port COM4 Created 6:30:48 AM.
System.IO.IOException: A device attached to the system is not functioning.

   at System.IO.Ports.InternalResources.WinIOError(Int32 errorCode, String str)
   at System.IO.Ports.SerialStream.EndWrite(IAsyncResult asyncResult)
   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 ModbusPortManager.TransmitPacket(IModbusDevice device, ComPacket packet, Int32 packetIndex) in Classes\ModbusPortManager.cs

-----------------------------------------------------------------------------

11:26:35.880, Disposing Timers. Stopped MessageReceived EventWaitHandle. Stopped PacketTimeoutTimer Timer. Stopped RetransmitTimer Timer. Stopped AgePrioritizerTimer Timer. Stopped 4/4. ~ ModbusPortManager Port COM4 Created 6:30:48 AM Disposed

-----------------------------------------------------------------------------

11:26:35.894, Exception attempting to close on ModbusPortManager Port COM4 Created 6:30:48 AM Disposed.
System.UnauthorizedAccessException: Access to the port is denied.
   at System.IO.Ports.InternalResources.WinIOError(Int32 errorCode, String str)
   at System.IO.Ports.InternalResources.WinIOError()
   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 ModbusPortManager.DisposeComPort() in Classes\ModbusPortManager.cs

-----------------------------------------------------------------------------

11:26:35.904, Disposing Com Port. Com Port Events Unsubscribed. Com Port Disposed. ~ ModbusPortManager Port COM4 Created 6:30:48 AM Disposed

-----------------------------------------------------------------------------

11:26:36.934, Port Manager Created. ~ ModbusPortManager Port COM4 Created 11:26:36 AM

-----------------------------------------------------------------------------

11:26:36.947, Exception Testing on ModbusPortManager Port COM4 Created 11:26:36 AM

System.UnauthorizedAccessException: Access to the port 'COM4' is denied.
   at ModbusPortManager.OpenPort() in Classes\ModbusPortManager.cs
   at ModbusPortManager.TestPort() in Classes\ModbusPortManager.cs

-----------------------------------------------------------------------------
c#
serial-port
dispose
unauthorizedaccessexcepti
asked on Stack Overflow Feb 14, 2019 by adragon202 • edited Feb 14, 2019 by adragon202

1 Answer

1

Ultimately ended up solving the issue of the System.ObjectDisposedException by implementing the solution from ObjectDisposedException when closing SerialPort in .Net 2.0 and the class from http://zachsaw.blogspot.com/2010/07/net-serialport-woes.html

SerialPortFixer class throws invalid parameters on some ports, but on my device it did not and the exception no longer occurs that crashed the program on reconnect.

answered on Stack Overflow Feb 15, 2019 by adragon202

User contributions licensed under CC BY-SA 3.0