WindowsMobile: приложение выходит после обработки исключения из DialogForm - PullRequest
2 голосов
/ 07 апреля 2009

У меня есть следующий простой сценарий:

DialogForm с кнопкой, Button_click генерирует исключение.

MainForm с кнопкой и меткой, в клике я показываю новый экземпляр DialogForm внутри блока Catch.

Если я запускаю эту настройку в обычных WinForms, я могу поймать исключение, как и ожидалось.

Если я запускаю это в WinMobile (я тестировал на WM5 и WM6 Pro), я вижу с помощью отладчика, что блок Catch введен , но исключение продолжает расти , и приложение умирает.

Код в MainForm выглядит следующим образом:

try
{
   using (DialogForm frm = new DialogForm())
   {
     DialogResult r = frm.ShowDialog();
     label1.Text = r.ToString();
  }
}
catch (Exception ex)
{
  label1.Text = ex.Message;
}

Edit:

Я исследовал немного дальше, с блоком catch {} вокруг этого кода и вокруг Application.Run (), и приложение все еще закрывается.

По-видимому, это , а не Исключение, которое можно поймать и обработать очень хорошо. Но после этой операции похоже, что приложение выполняет нежелательный Exit ().

Ответы [ 8 ]

5 голосов
/ 10 апреля 2009

После повозки я нашел что-то, что работает:

try {
  // show Dialog that Throws
}
catch (Exception ex) {
  label1.Text = ex.Message;
  Application.DoEvents();  // this solves it
}

Щедрость по-прежнему открыта для всех, кто может сказать мне , почему необходим DoEvents ().

5 голосов
/ 14 апреля 2009

Причина, по которой вам нужно DoEvents, состоит в том, что это очищает очередь сообщений, пока форма еще доступна.

Что происходит, так это то, что все еще есть сообщения, ожидающие обработки против формы, генерирующей исключение. Вызывая DoEvents, вы разрешаете их обработать до того, как блок using очистит форму и остановит обработку сообщений в очереди.

2 голосов
/ 17 февраля 2011

https://connect.microsoft.com/VisualStudio/feedback/details/94356/modal-windows-in-net-compact-framework-application-stop-working-if-unhandled-exception-on-modal-dialog-is-raised#tabs

В компактной среде 2.0 это общепринятая проблема ... им все равно ...

Если вы используете showdialog внутри попытки, как только вы поймали исключение, showdialod больше не работает ....

2 голосов
/ 10 апреля 2009

Лучшая информация, которую я могу найти по этому поводу, это тот факт, что вы вызываете ShowDialog ().

Я пытался использовать Reflector, но он не обрабатывает CF-библиотеки. Так что лучшее сравнение - посмотреть на основной файл без CF. В нем, если вы отслеживаете функцию ShowDialog (), она в конечном итоге вызывает Application.RunDialog (form). Там он создает новый контекст потока и запускает свой собственный цикл сообщений для диалогового окна.

Так как я не могу заглянуть в настоящую CF DLL, я могу только сделать "обоснованное предположение". Казалось бы, это связано с тем, что исключение происходит в отдельном цикле сообщений и не будет правильно перехвачено, если вы не обработаете очередь сообщений приложения с помощью DoEvents ().

Таким образом, ShowDialog () приводит к тому, что исключение создается в отдельном цикле сообщений, и тот факт, что оно перехватывается, не обрабатывается правильно, пока вы не вызовете DoEvents ().

Что произойдет, если вы попробуете обычное шоу ()? Вам все еще нужны DoEvents? У меня нет среды, чтобы проверить это, поэтому я могу только предложить вам попробовать. Если вы измените его на Show () и больше не будете нуждаться в DoEvents (), я думаю, что тогда мы точно будем знать, был ли я прав.

1 голос
/ 13 апреля 2009

Основываясь на других ответах и ​​моих комментариях относительно необходимых DoEvents: Вы пытались проверить в своем первоначальном утверждении catch, может ли label1.InvokeRequired быть true?

Если это так, у вас может быть какое-то состояние гонки, связанное с несколькими потоками, потому что вы устанавливаете label1.Text для свойства класса исключения, выданного из другого потока?

В обычном .NET 1.0 это часто просто работало, а не должно. В более поздних версиях игнорирование InvokeRequired == true приводит к исключению. Я не уверен, как Compact Framework обрабатывает такие "нарушения". Может быть, тогда существует процесс?

1 голос
/ 10 апреля 2009

Может быть, перехват AppDomain.CurrentDomain.UnhandledException (вместе с подсказкой Джоэла) решит вашу проблему с исключением? Может быть аналогом этого другого ответа .NET .

Я использую следующий код

    try
    {
        AppDomain.CurrentDomain.UnhandledException +=
            (object sender, UnhandledExceptionEventArgs e) =>
            {
                CrashOn((Exception)e.ExceptionObject, e.IsTerminating);
            };
        var mainWindow = new MainWindow();
        MobileDevice.Hibernate += (sender, e) => { mainWindow.Hibernate(); };
        Application.Run(mainWindow);
    }
    catch (Exception huh)
    {
        CrashOn(huh, false);
    }

в Program.Main() моего WM6 Профессионального твиттер-клиента . Здесь метод CrashOn() сохраняет информацию об исключении на диск и запускает исполняемый файл аварийного восстановления. Затем он показывает информацию о сбое клиента, имеет возможность отправить мне информацию об исключительной ситуации и дает возможность использовать либо выход, либо перезапуск клиента.

1 голос
/ 07 апреля 2009

Хотя в документации по программированию указывалось бы, что следующая конструкция не нужна, я обнаружил, что иногда я должен использовать следующее.

try
{
 using (DialogForm frm = new DialogForm())   
 {     
       DialogResult r = frm.ShowDialog();
       label1.Text = r.ToString();  
 }
}
catch (Exception ex)
{
    label1.Text = ex.Message;
}
catch
{
    label1.Text = "Unknown Exception";
}
0 голосов
/ 10 апреля 2009

Напоминаю, что точка-сеть имеет обработчик исключений по умолчанию, который срабатывает, когда исключение пересекает определенную границу. Именно этот обработчик заставляет ваше приложение закрываться. Я помню, как смотрел эту проблему некоторое время назад, но, к сожалению, больше не имею доступа к коду. Что касается различий в поведении между .NET и .NET CF, то это потому, что эти два обрабатывают фреймы по-разному (возможно, у фреймов в CF нет родителей или что-то подобное).

Вы можете подключиться к обработке исключений по умолчанию и делать все, что угодно ... Я думаю, что код, который я реализовал, был следующим: Необработанные исключения

...