2011-01-07 2 views
3

Je suis en train de développer un framework MVF MVF léger, et je souhaiterais être en mesure d'intercepter des exceptions non gérées et, idéalement, de les récupérer.Attraper des exceptions dans WPF au niveau de FrameWork

Ignorant pour le moment tous les bons arguments pour ne pas faire cela, je rencontre la situation suivante:

Si j'enregistre un gestionnaire pour AppDomain.CurrentDomain.UnhandledException dans la méthode OnStartup du App.xaml.cs, comme suit ...

App.xaml.cs:

protected override void OnStartup(StartupEventArgs e) 
{ 
    AppDomain.CurrentDomain.UnhandledException += new 
    UnhandledExceptionEventHandler(this.AppDomainUnhandledExceptionHandler); 

    base.OnStartup(e); 
} 


void AppDomainUnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs ea) 
{ 
    Exception e = (Exception)ea.ExceptionObject; 
    // log exception 
} 

puis soulever une exception dans l'un de mes machines virtuelles, le gestionnaire est appelé comme prévu. Jusqu'ici tout va bien, à part le fait que je ne peux pas récupérer cette approche, tout ce que je peux faire, c'est consigner l'exception et laisser le CLR terminer l'application.

Ce que je voulais réellement faire est de récupérer, et de retourner le contrôle à la machine virtuelle principale. (Encore une fois mettre de côté les motivations contre cela).

Donc, faire un peu de lecture, je décide d'enregistrer un gestionnaire d'événements pour AppDomain.CurrentDomain.UnhandledException au même endroit, de sorte que le code ressemble maintenant quelque chose comme ça ...

protected override void OnStartup(StartupEventArgs e) 
{ 
    AppDomain.CurrentDomain.UnhandledException += 
    new UnhandledExceptionEventHandler(this.AppDomainUnhandledExceptionHandler); 

    this.DispatcherUnhandledException += 
    new DispatcherUnhandledExceptionEventHandler(DispatcherUnhandledExceptionHandler); 

    base.OnStartup(e); 
} 

void AppDomainUnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs ea) 
{ 
    Exception e = (Exception)ea.ExceptionObject; 
    // log exception 
} 

void DispatcherUnhandledExceptionHandler(object sender, DispatcherUnhandledExceptionEventArgs args) 
{ 
    args.Handled = true; 
    // implement recovery 
} 

La question est Une fois que j'ai enregistré le gestionnaire pour this.DispatcherUnhandledException, aucun gestionnaire de l'événement est appelé. L'enregistrement de DispatcherUnhandledExceptionHandler désactive donc le gestionnaire pour AppDomain.CurrentDomain.UnhandledException.

Est-ce que quelqu'un a une approche pour attraper et récupérer à partir d'exceptions VM non gérées?

Il peut être important de mentionner qu'il n'y a pas d'utilisation explicite du thread dans le framework.

Répondre

5

La raison que VS vous montre l'exception est parce que vous l'avez configuré comme cela (soit vous l'avez fait explicitement ou - plus probablement - les valeurs par défaut dans VS l'ont configuré comme ceci). Vous pouvez contrôler ce que Visual Studio fait lorsqu'il rencontre une exception dans le code débogué via le menu Debug->Exceptions.

Vous pouvez même le faire se casser même si vous avez un attrape pour cela, qui est assez pratique dans certains cas. Si vous n'utilisez pas le multi-threading, l'événement DispatcherUnhandledException ne devrait pas poser de problème car il capture tout ce qui n'est pas capturé sur le thread principal de l'interface utilisateur.

+0

Merci Isak, il est important de savoir que j'attraperai toutes les exceptions que je suis susceptible de générer. –

2

Une réponse rapide à ma propre question:

Cela fonctionne ...

App.xaml.cs:

protected override void OnStartup(StartupEventArgs e) 
{ 
    Application.Current.DispatcherUnhandledException += 
    new DispatcherUnhandledExceptionEventHandler(DispatcherUnhandledExceptionHandler); 

    base.OnStartup(e); 
} 

void DispatcherUnhandledExceptionHandler(object sender, DispatcherUnhandledExceptionEventArgs args) 
{ 
    args.Handled = true; 
    // implement recovery 
    // execution will now continue... 
} 

[Edit: Mes commentaires ci-dessous ont rien à voir avec la mise en œuvre , mais mon IDE spécifique (Visual Studio) config en ce qui concerne l'exception attraper par l'IDE. S'il vous plaît voir les commentaires d'Isak ci-dessus.MAIS, et c'est un gros problème, mais si vous exécutez depuis VisualStudio, la boîte de dialogue de notification d'exception VS apparaîtra alors, et le DispatcherUnhandledExceptionHandler ne sera invoqué que si vous appuyez sur F5/continue, après quoi l'exécution se poursuivra comme d'habitude.

Si vous exécutez le fichier binaire compilé directement, par exemple depuis la ligne de commande ou via l'Explorateur Windows, le gestionnaire sera appelé comme vous le souhaitez, sans aucun popup intermédiaire.

Questions connexes