我正在使用 .NET 4 SerialPort 对象与连接到 COM1 的设备通信。
当我完成对设备的操作后,我在 SerialPort 上调用 Close。我不调用 Dispose,但我相信 Close 和 Dispose 在这里是同义词。
通常这工作得很好。
然而,有时我会在一段时间后收到以下异常(我看到的时间范围为 5 毫秒到 175 毫秒):
System.ObjectDisposedException: Safe handle has been closed 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.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart()
我的代码都不在这个堆栈上。
我找到了 http://blog.zachsaw.com/2010/07/serialport-ioexception-workaround-in-c.html ,但那里的解决方案不起作用。进一步检查,问题是 IOException
,而不是 ObjectDisposedException
。
有很多帖子涉及拔下 USB 转串口设备时观察到的问题,但 COM1 是板载的,因此它不会意外消失。
问题here也不是我的问题; SerialPort 在其使用期间保持事件状态,并且仅在我完成与设备的通话后才关闭。 (完成后,设备处于不会传输任何进一步数据的状态。)
SLaks suggests在 SafeHandle.Dispose
的入口处设置一个断点,以确定我何时处理我不应该处理的东西,但我多次触发该断点。当我使用完串行设备时,我对 SerialPort.Close
的一次调用调用了三次,其余的大约一半在 GC 线程中。其余部分似乎与 WPF UI 元素有关。
我现在很迷茫。我从这里去哪里?
有没有办法确定哪个 SafeHandle 属于哪个对象,这样我就可以确定我没有意外处置它?
除了 Close 我需要正确关闭 SerialPort 之外还有其他咒语吗?
最佳答案
我也遇到过这个问题,自从我开始使用以下两条规则后,我再也没有遇到过。
- 始终调用 Close(),然后调用 Dispose()。
- 切勿重复使用 SerialPort 对象,始终在需要重新打开端口时创建一个新对象。
我知道,它们不是什么新闻,但它一直对我有用。
关于c# - 关闭 .NET SerialPort 后的 ObjectDisposedExecption,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7113909/