ObjectDisposedExecption после закрытия .NET SerialPort

Я использую объект SerialPort .NET 4 для связи с устройством, подключенным к COM1.

Когда я заканчиваю с устройством, я вызываю Закройте 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 принадлежит какому объекту, чтобы я мог быть уверен, что не утилизирую его неожиданно?
Есть ли какое-нибудь заклинание, кроме закрытия, мне нужно правильно закрыть SerialPort?

10
задан Community 23 May 2017 в 11:59
поделиться