Как заставить WinForms молча игнорировать необработанные исключения?
Это становится крайне раздражающим. Сейчас у меня есть приложение winforms, и все работает неправильно, но никаких исключений не было, насколько я мог судить. После прохождения почти всех частей соответствующего кода выясняется, что в начале моего приложения было выбрано исключение.
Короче говоря, в WinForms, насколько это невероятно, если возникает исключение, библиотека WinForms игнорирует его. Нет «произошло необработанное исключение». Выдается сообщение JIT, оно просто прекращает обработку текущего события и возвращается к графическому интерфейсу.
Это вызывает случайные ошибки, поскольку код для загрузки данных не вызывается из-за исключения, возникшего до загрузки этих данных.
- Java List.add () UnsupportedOperationException
- Почему я не должен обертывать каждый блок в «try» - «catch»?
- Открытый Java-обработчик исключений Java
- Исключение брошено внутри блока catch - будет ли оно поймано снова?
- c ++ exception: throwing std :: string
Чтобы увидеть это в действии, я создал совершенно новое приложение WinForms и ввел следующий код:
public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { string blah = null; blah.Trim(); } }
Нажмите F5 и загрузите форму без каких-либо ошибок, даже если выбрана нулевая ссылка.
Затем я попытался перейти к основному методу Program.cs
и добавить Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException);
к нему. Тем не менее моя форма загружается без каких-либо ошибок.
Несмотря на то, что я знаю, что могу сказать VS, чтобы ломать все исключения, я считаю эту ситуацию очень плохой. Это вызывает действительно серьезные проблемы, которые трудно отлаживать в процессе производства, и поскольку это внутренний инструмент, я действительно хочу его иметь, поэтому на самом деле ошибки возникают, когда возникает исключение, а не молча игнорирует его.
Кто-нибудь знает как это сделать?
Обновление: просто для обновления вещей, которые я узнал из комментариев.
Это похоже на 64-разрядную проблему с windowsми, как я узнал из этого вопроса, который я не видел перед публикацией. В этом вопросе он указал на отчет об ошибке Microsoft об этом, который имел это сказать:
Здравствуйте,
Эта ошибка была закрыта как «Внешняя», потому что это поведение объясняется тем, как x64 версия Windows обрабатывает исключения. Когда исключение пользовательского режима пересекает переход ядра, x64 версии Windows не позволяют распространению исключения. Поэтому прикрепленные отладчики не знают о том, что произошло исключение, в результате чего отладчик не смог сломать необработанное исключение.
К сожалению, ничто из того, что команда Visual Studo не может сделать для решения этой проблемы, является результатом разработки операционной системы. Все отзывы по этому вопросу должны быть адресованы команде Windows; однако команда Windows считает, что это «правильный» дизайн операционной системы, и считает поведение x86 «неправильным».
С наилучшими пожеланиями, отладчик Visual Studio
При этом сборки, которые не запускаются через визуальную студию (или с помощью Ctrl + F5 для запуска), похоже, показывают сообщение об ошибке JIT exception EXCEPT, если у вас есть следующий код в Program.cs
:
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException);
Этот код заставит windows игнорировать исключение.
Однако, если вы (вместо этого) подписываетесь на событие Application.ThreadException
, будут исключены не только ваши исключения, отладчик visual studio будет разбиваться на необработанные исключения!
- Исключение, брошенное в catch и finally clause
- «Ошибка NoClassDefFoundError: Не удалось инициализировать class»
- Android Studio IDE: перерыв на исключении
- В C #, как я могу rethrow InnerException без потери трассировки стека?
- Когда нужно поймать java.lang.Error?
- Хорошие шаблоны для обработки ошибок VBA
- Почему я должен всегда делать свои Исключения ? (.СЕТЬ)
- Разница между C ++ 03 throw () specifier C ++ 11 noexcept
В основной функции Program.cs вы также должны убедиться, что вы завернули свой вызов, чтобы открыть форму в try / catch. Кроме того, используйте исключение AppDomain.UnhandledException
для исключения исключений. Мы также добавляем Application.ThreadException
.
Я считаю, что следующее приведет вас к перехватам всех исключений, которые могут быть выбраны …
static void Main() { try { System.Windows.Forms.Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); System.Windows.Forms.Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(OnGuiUnhandedException); AppDomain.CurrentDomain.UnhandledException += OnUnhandledException; var form = new MainForm(); form.ShowDialog(); } catch (Exception e) { HandleUnhandledException(e); } finally { // Do stuff } } private static void HandleUnhandledException(Object o) { // TODO: Log it! Exception e = o as Exception; if (e != null) { } } private static void OnUnhandledException(Object sender, UnhandledExceptionEventArgs e) { HandleUnhandledException(e.ExceptionObject); } private static void OnGuiUnhandedException(object sender, System.Threading.ThreadExceptionEventArgs e) { HandleUnhandledException(e.Exception); }
Попробуйте следующее.
- Исключайте исключения в основной точке ввода приложения.
- Кроме того, управляйте необработанными исключениями streamов с помощью ThreadExceptionEventHandler
Это fragment кода:
[STAThread] public static void Main(string[] args) { try { Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException); //your program entry point } catch (Exception ex) { //manage also these exceptions } } private void Application_ThreadException(object sender, ThreadExceptionEventArgs e) { ProcessException(e.Exception); }
Легкое исправление не запускается под отладчиком.
По какой-то причине отладчик маскирует исключение. Если вы обычно запускаете приложение (Ctrl + F5), вы получите обычное «Необработанное исключение» в вашем приложении … Продолжить / выйти? » Диалог.
Испытывая это часто и выявляя проблему 64-разрядной ОС и события Form.Load, я всегда делаю все возможное, чтобы выполнять все мои функции запуска в событии Form.Shown. Для всех практических целей это одно и то же (кроме нескольких редких, исключительных обстоятельств), и сообщение JIT создается в событии Shown.