我正在使用.NET 4 SerialPort对象与连接到COM1的设备进行通讯。

对设备完成操作后,我在SerialPort上调用Close。我不称其为Dispose,但我相信Close和Dispose在这里是同义词。

通常这可以正常工作。

但是,有时有时会在一段时间后出现以下异常(我看到的时间范围是5毫秒至175毫秒):

System.ObjectDisposedException:安全句柄已关闭
在System.Runtime.InteropServices.SafeHandle.DangerousAddRef( bool 值和成功)
在System.StubHelpers.StubHelpers.SafeHandleAddRef(SafeHandle pHandle, bool 值和成功)
在Microsoft.Win32.UnsafeNativeMethods.GetOverlappedResult(SafeFileHandle hFile,NativeOverlapped * lpOverlapped,Int32&lpNumberOfBytesTransferred, bool 值bWait)
在System.IO.Ports.SerialStream.EventLoopRunner.WaitForCommEvent()
在System.Threading.ThreadHelper.ThreadStart_Context(对象状态)
在System.Threading.ExecutionContext.Run(ExecutionContext执行上下文,ContextCallback回调,对象状态, bool ignoreSyncCtx)
在System.Threading.ExecutionContext.Run(ExecutionContext执行上下文,ContextCallback回调,对象状态)
在System.Threading.ThreadHelper.ThreadStart()

我的代码都没有在此堆栈上。

我找到了http://blog.zachsaw.com/2010/07/serialport-ioexception-workaround-in-c.html,但是那里的解决方案没有用。在进一步检查中,问题出在IOException,而不是ObjectDisposedException

有很多关于拔出USB到串行设备但COM1已安装的观察到的问题的文章,因此它不会意外消失。

问题here也不是我的问题。在使用期间,SerialPort保持事件状态,并且仅在与设备通话后才关闭。 (完成后,设备将处于不会再传输任何数据的状态。)

SLaks suggestsSafeHandle.Dispose的入口处设置一个断点,以确定我何时处置本不应该的东西,但是我击中了该断点数十次。当我使用串行设备完成操作时,单次调用SerialPort.Close会调用3次,其余大约一半在GC线程中。其余似乎与WPF UI元素有关。

我现在很茫然。我从这里去哪里?

有没有一种方法可以确定哪个SafeHandle属于哪个对象,因此可以确定我不会意外处置它?
除了关闭我需要正确关闭SerialPort以外,还有其他问题吗?

最佳答案

我也遇到了这个问题,而且自从我开始使用以下两个规则以来,我再也没有看到它。

  • 始终先调用Close(),再调用Dispose()。
  • 从不重用SerialPort对象,当需要重新打开端口时,请始终创建一个新对象。

  • 我知道,这不是什么新闻,但它对我有用。

    关于c# - 关闭.NET SerialPort后的ObjectDisposedExecption,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7113909/

    10-10 19:31