Мне тоже было интересно об этом, и я так и не смог найти что-либо о какой-либо конкретной опции встроенной конфигурации, которую вы могли бы установить (может быть, но я так и не нашел упоминания о том, что это было). Я думаю, мы также обнаружили, что поведение по умолчанию (если вы ничего не делаете) эквивалентно режиму ThrowException, в отличие от того, что MSDN подразумевает в этой цитате. Кроме того, я считаю, что установка его в режим «Автоматически» эквивалентна тому, чтобы вообще не касаться его; для начала он уже в автоматическом режиме.
Однако я обнаружил, что есть две перегрузки SetUnhandledExceptionMode
. Обычный работает для каждого потока (обычно у вас есть только один поток пользовательского интерфейса, в любом случае), но второй также принимает логическое значение, которое определяет, применяется ли параметр только к текущему потоку (true) или ко всем потокам пользовательского интерфейса. (ложный). Передача false действует как установка параметров по умолчанию для будущих потоков пользовательского интерфейса, если они остаются установленными в режиме Automatic
при запуске (под этим я подразумеваю циклы сообщений, т. Е. Вызовы Application.Run
), и вы можете подключить свой собственный параметр конфигурации сделать этот вызов, чтобы установить свой глобальный по умолчанию. Я должен задаться вопросом, действительно ли это то, к чему они действительно стремились с помощью расплывчатой ссылки "config".
Однако предостережение заключается в том, что вызов SetUnhandledExceptionMode
должен быть выполнен до создания любого дескриптора окна в том же контексте. Поэтому вызов его с помощью false необходимо выполнить до создания какого-либо дескриптора окна в потоке любого потока . Кроме того, отладчик Visual Studio, по-видимому, заставляет существовать дескриптор окна до запуска вашего кода, поэтому этот вызов никогда не может завершиться успешно (при значении false) при отладке. Однако этот дескриптор окна находится не в вашем потоке, поэтому обычный вызов (или с true) можно безопасно выполнить в сценарии отладки. Я не уверен, как это происходит в других случаях, когда приложение WinForms находится в созданном поддомене, а не в верхнем / начальном домене, наследует ли поддомен флаг any-handle-созданный или начинает заново. Возможно, в этом и заключается проблема Visual Studio.
Обычный вызов (или с true) все еще должен быть выполнен до создания какого-либо дескриптора окна в этом потоке. Я полагаю, что этот параметр сохранится и после выхода из контекста приложения, если вы затем повторно введете Application.Run
в том же потоке (как и флаг, созданный дескриптором, который прерывает дальнейшие вызовы, чтобы изменить его). Но имейте в виду, что подписка на Application.ThreadException
основана на потоках, контекстах и будет потеряна при выходе Application.Run
. Он также может иметь только одного подписчика (перезаписывает любого предыдущего подписчика) и не может быть изменен во время работы цикла сообщений. Поэтому, если вы звоните Application.Run
снова, вы должны повторно подписаться на Application.ThreadException
перед вызовом Application.Run
, или они вместо этого будут перехвачены и отправлены в обработчик WinForms по умолчанию (я не имею в виду UnhandledException), потому что параметр "режим исключения" сохраняется. Обычно вы не продолжаете входить и выходить из цикла сообщений в одном и том же потоке, так что это не проблема, но мы столкнулись с этим, потому что мы должны были сделать это в Gibraltar.Agent .
AppDomain.UnhandledException
, однако, является обычным событием с несколькими подписчиками и не зависит от потока. Подпишитесь на него один раз, и вы получите покрытие всего домена приложений (например, CurrentDomain).