2012-04-17 14 views
9

Natknąłem się na taką sytuację. Aplikacja WinForm ma dwa formularze. Główna forma ma przycisk, kiedy użytkownik kliknie, pokazane zostanie modalne okno dialogowe. Formularz dialogowy ma również przycisk, gdy użytkownik go kliknie, zostanie zgłoszony wyjątek.Zachowanie się podczas obsługi wyjątków w aplikacji WinForms, która korzysta z modalnego okna dialogowego

Obsługa wyjątków różni się, gdy aplikacja działa w trybie debuggera i działa sama. Oto minimalny kod, odtwarzając ten problem:

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     try 
     { 
      using (var dialog = new Form2()) 
      { 
       dialog.ShowDialog(); 
      } 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show("Oops! " + ex.Message); 
     } 
    } 
} 

public partial class Form2 : Form 
{ 
    public Form2() 
    { 
     InitializeComponent(); 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     throw new NotImplementedException(); 
    } 
} 

Gdy debugowanie, podnoszenie wyjątek zamyka okno i obsługi wyjątków w Form1.button1_Click obsługuje wyjątek.

Po uruchomieniu samej aplikacji zgłoszenie wyjątku nie powoduje zamknięcia okna dialogowego. Zamiast tego wywoływana jest domyślna procedura obsługi Application.ThreadException.

Dlaczego (i po co) zachowanie się różni? Jak dostosować to do siebie?

Odpowiedz

8

Spróbuj tego w Program.Main():

[STAThread] 
static void Main() 
{ 
    Application.EnableVisualStyles(); 
    Application.SetCompatibleTextRenderingDefault(false); 
    Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException); 
    Application.Run(new Form1()); 
} 

Powodem jest to, aby zrobić ze sposobu Windows Forms zespoły są prowadzone poza procesem Hosting Visual Studio. Zobacz to:

http://msdn.microsoft.com/en-us/library/system.windows.forms.application.threadexception.aspx

Jeśli ustawisz powyższy wiersz kodu:

Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); 

i uruchomić go w VS, widać co domyślnym zachowaniem - okno dialogowe, do którego które polecisz, zostanie pokazane, gdy przekroczysz początkowy wyjątek w kodzie. Wartość domyślna jest po prostu różna w zależności od tego, czy działasz w trybie hostowanym, czy autonomicznym.

Cóż, „dlaczego” jest rodzajem pokryte link MS - błąd występuje w obsługi zdarzeń, który jest na innym wątku. Domyślnym zachowaniem jest traktowanie tego inaczej, tylko w WinForm. Jeśli umieścisz ten wiersz po wywołaniu okna:

throw new Exception("Bah!"); 

i zachować zachowanie na CatchException widać, że idzie do obsługi wyjątków, jak można by oczekiwać. Jest to tylko wyjątek w procedurze obsługi zdarzeń, który jest przetwarzany inaczej. Nadzieja, która pomaga.

+0

dzięki! To jest odpowiedź na pytanie "jak" część mojego pytania. "Dlaczego i co za" jest nadal aktualne ... – Dennis

+2

Pojmowane; The Why/What For I postawiłbym na to, że jest to jedna z dziwactw platformy .NET. Mogę sprostować i chciałbym wiedzieć, czy ktokolwiek zna dobry powód, dla którego to zachowanie jest różne w zależności od kontekstu, w którym aplikacja jest uruchomiona. Zgadzam się, że to trochę niedobre. –

Powiązane problemy