Я испытал следующее. В большом приложении, которое показывает дочернюю форму MDI, исключение в дочерней форме также закрывает родительскую форму.WinForms: Почему Dispose вызывается из RunMessageLoopInner?
Я пытаюсь поймать исключение и показать сообщение об ошибке в специальной форме ошибки. Желательным поведением было бы уловить исключение без размещения родительской формы. В дочерней форме у меня есть кнопка, которая вызывает исключительный
throw new ApplicationException("test");
Если я ставлю точку останова в основной форме (родительский MDI) Dispose метод
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose(disposing);
}
я получаю следующий вызов в стек
myApp.dll!myForm.Dispose(bool disposing)
System.dll!System.ComponentModel.Component.Dispose()
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadWindows.Dispose()
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.DisposeThreadWindows()
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.Dispose(bool postQuit)
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(int reasion, System.Windows.Forms.ApplicationContext context)
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoop(int reasion, System.Windows.Forms.ApplicationContext context)
System.Windows.Forms.dll!System.Windows.Forms.Application.Run()
с утилизацией true.
После этого исключение, которое я хочу, чтобы поймать действительно поймал, как и ожидалось в ИВК заявлении примерки поймать, но затем МДИ родительская форма уже закрыта (почему?).
Вот некоторый код, показывающий, как работает моя верхний уровень примерки загвоздка:
public class MainApplication
{
[STAThread]
static void Main(string[] args)
{
Application.ThreadException += MyThreadExceptionHandler;
try
{
OurMain(args);
}
catch(Exception ex)
{
MessageBox.Show(ex.Message + "\n" + ex.StackTrace, "Fatal Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
}
}
private static void MyThreadExceptionHandler(object sender, ThreadExceptionEventArgs e)
{
MessageBox.Show(e.Exception.Message + "\n" + e.Exception.StackTrace, "Fatal Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
}
private static void OurMain(string[] args)
{
//run the application
}
}
С моим вопросом здесь я ищу стратегии для решения этой проблемы и узнать, почему родительскую форму MDI закрывается (и, наконец, препятствует ее закрытию).
То, что я думаю, что я знаю, до сих пор:
- Я думаю, это не проблема многопоточности (. Кстати я также обрабатывать ThreadException событие и ничего не получить там), потому что я могу поймать исключение в пользовательском интерфейсе нить.
Примечание: Я задал вопрос очень общим образом. Скажите, пожалуйста, какая информация будет актуальна для вас, чтобы иметь возможность ответить на вопрос.
решение в моем конкретном случае:
В моем случае решение было не только обрабатывать Application.ThreadException
но также использовать другой вариант, как описано в this answer. В моем случае обработка Dispatcher.CurrentDispatcher.UnhandledException
выполнила эту работу. Application.ThreadException
кажется, работает только для чистых WinForms, но я инкапсулировал веб-представление, и привязка к веб-просмотру вызвала исключение, и Application.ThreadException
не отреагировал на это.
В 'program.cs' подключите [Application.ThreadException] (https://msdn.microsoft.com/en-us/library/system.windows.forms.application.threadexception (v = vs.110).) .aspx) Событие и принять меры оттуда ... –
@Idle_Mind: Как можно прочитать в вопросе, я обрабатываю это событие ... – Sjoerd222888
Извинения ... у вас есть: _after исключение, которое я хочу поймать, действительно поймано как ожидается на верхнем уровне утверждения try-catch, но затем основная форма уже удалена. Где этот try/catch? Можете ли вы показать этот код? –