Как отладить ошибку "Безопасная ручка была закрыта"
Код, который я унаследовал, продолжает сильно сбой со следующей ошибкой (не изменен вообще):
System.ObjectDisposedException: Safe handle has been closed
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.runTryCode(Object userData)
at System.Runtime.CompilerServices.RuntimeHelpers.
ExecuteCodeWithGuaranteedCleanup(
TryCode code, CleanupCode backoutCode, Object userData)
at System.Threading.ExecutionContext.RunInternal(
ExecutionContext executionContext, ContextCallback callback,
Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext,
ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
Это происходит только тогда, когда предыдущие разработчики добавили AppDomain.UnhandledException Event.
Если я удалю его, приложение просто вылетает с сообщением Dr Watson (отправьте отзыв и т.д.), а не обычным диалоговым окном .NET(с опцией продолжения и трассировкой стека).
Я проверил и не связан с Thread.Abort
Как я могу попытаться найти причину этой проблемы, как она кажется, из трассировки стека, а не быть в коде приложения?
Ответы
Ответ 1
Из того факта, что ссылаются на System.IO.Ports.SerialStream.EventLoopRunner.WaitForCommEvent() и Microsoft.Win32.UnsafeNativeMethods, я бы поставил под угрозу, что у вас есть COM-компонент, который имеет внутренние потоки, обращающиеся к порту, например. для последовательных или TCP/IP-данных.
Было бы похоже, что поток генерирует исключение во время его последовательности запуска. Возможно, он пытается получить доступ к недоступному или несуществующему порту. Это не удается, и исключение не обрабатывается и, таким образом, проталкивается обратно через код.
Попытка регистрации дополнительной информации из события UnhandledException, чтобы получить представление о том, где это может начаться.
Ответ 2
Добавление этого кода перед выполнением вызова иногда может помочь в этом (если причина в том, что информация о безопасности в новом потоке отсутствует:
AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
Предполагая, что вы используете проверку подлинности Windows. Он гарантирует, что созданные потоки создаются с правильным контекстом безопасности.
Документация доступна здесь:
https://msdn.microsoft.com/en-us/library/system.security.principal.principalpolicy(v=vs.110).aspx