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?
I've had this issue too, and since I started using the following two rules I've never seen it again.
- Always call Close() followed by Dispose().
- 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.
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