Я использую объект 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?