在SerialPort中,调用Close时拒绝访问,但不调用Dispose

问题描述 投票:1回答:1

更新1

我发现如果我颠倒了close / dispose的顺序,那么我从dispose而不是close中得到错误...所以可能一次性保护意味着该方法只被调用一次。

我已经能够通过在其中一条数据线上创建一个对地短路来复制我的设备上的错误。我正在我的设备上使用FT230x,发现如果我将复位引脚短接,那么通信就可以恢复,但是现在我的应用程序出现了一个不同的异常。所以从技术上讲,我的应用程序现在将在重新启动时重新连接,这是一个改进,在此之前我必须物理拔出并重新插入我的设备。下面的新例外:

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()

新的奇怪之处在于callstack不包含我的任何代码,Visual Studio不允许我将其追溯到我的代码。

原始邮政

我有一个设备在SerialPort.Write上给我一个IOException,然后当我尝试关闭端口时,我得到UnauthorizedAccessException。之后我可以毫无例外地处理serialport,但尝试重新打开端口会导致UnauthorizedAccessException。当我继续阅读Dispose和Close应该做同样的事情时,我真正的困惑就出现了。有没有办法可以在不重新启动程序(或在某些情况下是计算机)的情况下从中恢复?

在我的项目中,我管理多个使用相同Com端口或使用唯一com端口的设备。所以我有一个经理来管理我的设备,找到他们的端口,并为这些设备创建一个端口管理器。有时设备断开连接,当发生这种情况时,我关闭并处理com端口和com端口管理器。以下是我的代码:

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);
    }
}

我有一个设备每隔几天给我一次“System.IO.IOException:连接到系统的设备无法运行”,当我尝试ComPort.Write()时。当发生这种情况时,我试图处理我的com端口。在正常情况下,我可以关闭端口并重新打开它,但是在这种情况下我的代码无法关闭并成功处置,但是当我的设备管理器尝试重新打开com端口时,我继续获得UnauthorizedAccessException。以下是我的例外日志。

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
1个回答
1
投票

最终通过实现ObjectDisposedException when closing SerialPort in .Net 2.0的解决方案和http://zachsaw.blogspot.com/2010/07/net-serialport-woes.html的类来解决System.ObjectDisposedException的问题

SerialPortFixer类在某些端口上抛出无效参数,但在我的设备上它没有,并且不再发生在重新连接时崩溃程序的异常。

© www.soinside.com 2019 - 2024. All rights reserved.