更新1
我发现,如果我颠倒了关闭/处置的顺序,那么我会从处置而不是关闭中得到错误...因此,可能的一次性保护意味着该方法仅被调用一次。
通过在一条数据线上建立接地短路,我已经能够在设备上复制错误。我在设备上使用的是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()
奇怪的是,调用堆栈不包含我的任何代码,而Visual Studio不允许我将其追溯到我的代码。
原始帖子
我有一个在SerialPort.Write上给我IOException的设备,然后当我尝试关闭端口时,我得到了UnauthorizedAccessException。之后,我可以毫无例外地处理串行端口,但是尝试重新打开端口会导致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);
}
}
当我尝试ComPort.Write()时,每隔几天就有一个设备给我“ System.IO.IOException:连接到系统的设备无法运行”。发生这种情况时,我尝试处置我的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
-----------------------------------------------------------------------------
答案 0 :(得分:1)
最终通过实现ObjectDisposedException when closing SerialPort in .Net 2.0中的解决方案和http://zachsaw.blogspot.com/2010/07/net-serialport-woes.html中的类来解决System.ObjectDisposedException问题
SerialPortFixer类在某些端口上抛出了无效的参数,但是在我的设备上却没有,并且不再发生异常,该异常导致重新连接时使程序崩溃。