Я использую объект .NET 4 SerialPort для связи с устройством, подключенным к COM1.
Когда я закончу с устройством, я вызываю Close на SerialPort. Я не вызываю 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-to-serial отключено, но COM1 встроен, поэтому он не исчезает неожиданно.
Проблема здесь тоже не моя проблема; SerialPort поддерживается в течение всего времени его использования и закрывается только после завершения разговора с устройством. (Как только я закончу, устройство находится в состоянии, когда оно не будет передавать какие-либо дополнительные данные.)
SLaks предлагает установить точку останова на входе в SafeHandle.Dispose
, чтобы определить, когда я избавляюсь от того, чего не должен быть, но я бью эту точку останова десятки раз. Мой одиночный вызов три раза вызывается на SerialPort.Close
, когда я использую последовательное устройство, и около половины остальных находятся в потоке GC. Остальная часть, похоже, связана с элементами пользовательского интерфейса WPF.
Я сейчас в растерянности. Куда мне идти отсюда?
Есть ли способ определить, какой SafeHandle принадлежит какому объекту, так что я могу быть уверен, что не избавлюсь от него неожиданно?
Есть ли какие-нибудь заклинания, кроме Close, мне нужно правильно отключить SerialPort?