Какой элемент .config влияет на обработку исключений, если для UnhandledExceptionMode установлено значение UnhandledExceptionMode.Automatic? - PullRequest
9 голосов
/ 13 февраля 2009

У меня есть приложение Windows Forms, которое имеет этот код при запуске программы:

Application.SetUnhandledExceptionMode(UnhandledExceptionMode.Automatic);

В документации MSDN для UnhandledExceptionMode.Automatic указано, что:

Автоматически - маршрутизировать все исключения в обработчик ThreadException, если файл конфигурации приложения указывает иное.

Кто-нибудь точно знает, какой элемент / атрибут в файле конфигурации влияет на этот параметр?

Ответы [ 3 ]

5 голосов
/ 14 октября 2011

Вы можете добавить раздел JitDebugging в ваш файл конфигурации следующим образом:

<configuration>
  <system.windows.forms jitDebugging="true"/>
</configuration>

Это эквивалентно установке UnhandledExceptionMode на UnhandledExceptionMode.ThrowException (кстати, если вы запускаете приложение с подключенным отладчиком, эта опция автоматически включается).

Обратите внимание, что UnhandledExceptionMode.Automatic используется по умолчанию .Net, если не указано иное; Насколько я могу судить, единственная причина явно установить режим необработанного исключения в автоматический режим - это если вы хотите отменить предыдущий вызов, который изменил его на что-то другое. Обратите внимание, что если вы установите для него значение, отличное от Автоматически, настройки файла конфигурации не будут прочитаны.

Обратите внимание, что если вы присоедините ThreadException к текущему домену приложения, результат будет автоматически, как если бы вы установили UnhandledExceptionMode равным UnhandledExceptionMode.CatchException.

2 голосов
/ 29 июля 2009

Мне тоже было интересно об этом, и я так и не смог найти что-либо о какой-либо конкретной опции встроенной конфигурации, которую вы могли бы установить (может быть, но я так и не нашел упоминания о том, что это было). Я думаю, мы также обнаружили, что поведение по умолчанию (если вы ничего не делаете) эквивалентно режиму 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).

0 голосов
/ 13 февраля 2009

Может быть, это ответ на ваш вопрос? Обработка «необработанных исключений» в .NET 2.0

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...