ObjectDisposedExecption after closing a .NET SerialPort

我们两清 提交于 2019-12-14 03:40:06

问题


I am using a .NET 4 SerialPort object to talk to a device attached to COM1.

When I am done with the device, I call Close on the SerialPort. I do not call Dispose, but I believe that Close and Dispose are synonymous here.

Usually this works just fine.

Sometimes, however, I get the following exception some time later (The times I've seen range from 5 ms to 175 ms):

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

None of my code is on this stack.

I found http://blog.zachsaw.com/2010/07/serialport-ioexception-workaround-in-c.html, but the solution there did not work. On further inspection, the issue there is an IOException, not an ObjectDisposedException.

There are a plethora of posts concerning issues observed when a USB-to-serial device is unplugged, but COM1 is onboard, so it isn't vanishing unexpectedly.

The problem here is also not my issue; the SerialPort is kept alive for the duration of its use, and is closed only when I am done talking to the device. (Once I am done, the device is in a state where it will not transmit any further data.)

SLaks suggests setting a breakpoint on the entrance to SafeHandle.Dispose, to determine when I'm disposing something I shouldn't be, but I strike that breakpoint dozens of times. Three times are called by my single call to SerialPort.Close, when I am done using the serial device, and about half the rest are in the GC thread. The remainder seem to be related to WPF UI elements.

I am now at a loss. Where do I go from here?

Is there a way to determine which SafeHandle belongs to which object, so I can be certain I'm not disposing it unexpectedly?
Is there some incantation other than Close I need to properly shut down a SerialPort?


回答1:


I've had this issue too, and since I started using the following two rules I've never seen it again.

  1. Always call Close() followed by Dispose().
  2. Never reuse a SerialPort object, always create a new one when a port needs to be reopened.

I know, they aren't much news, but its been working for me.




回答2:


The call to disposed is documented behavior (see here) - I guess you try to read/write after Close (maybe in another thread). I would suggest wrapping the calls in a seperate class and setting a "closed"-flag. Then you should be able to find the problem rather fast.



来源:https://stackoverflow.com/questions/7113909/objectdisposedexecption-after-closing-a-net-serialport

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!