2011-02-03 11 views
5

Hola, intento implementar una solución desde este sitio en mi aplicación WPF para el manejo de excepciones globales.Excepción de manejo global en la aplicación WPF con Caliburn.Micro

http://www.codeproject.com/Articles/90866/Unhandled-Exception-Handler-For-WPF-Applications.aspx

utilizo Caliburn Micro como marco MVVM. Servicio que tengo en ensamble externo y se inyecta en clase de modelo de vista con MEF.

Aquí está mi implementación para el manejo de excepciones globales en la aplicación WPF.

clase App.xaml

  DispatcherUnhandledException="Application_DispatcherUnhandledException" 
     Startup="Application_Startup" 

Aplicación:

public partial class App : Application 
{ 
    private IMessageBox _msgBox = new MessageBoxes.MessageBoxes(); 

    public bool DoHandle { get; set; } 

    private void Application_Startup(object sender, StartupEventArgs e) 
    { 
     AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; 
    } 

    private void Application_DispatcherUnhandledException(object sender, 
          System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e) 
    { 
     if (DoHandle) 
     { 
      _msgBox.ShowException(e.Exception); 
      e.Handled = true; 
     } 
     else 
     { 
      _msgBox.ShowException(e.Exception); 
      e.Handled = false; 
     } 
    } 


    void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) 
    { 
     var ex = e.ExceptionObject as Exception; 
     _msgBox.ShowException(ex); 
    } 


} 

método de servicio de montaje externo:

public void ServiceLogOn() 
    { 
     try 
     { 

     } 
     catch (Exception ex) 
     { 

      throw ex; 
     } 
    } 

Este método es el servicio de llamada en la clase vista del modelo, por ejemplo, en el botón haga clic en evento:

[Export(typeof(ILogOnViewModel))] 
    public class LogOnViewModel : Screen, ILogOnViewModel 
    { 
     public void LogOn() 
     { 
      _service.ServiceLogOn(); 
     } 
    } 
  1. Ejecuto la aplicación WPF en Visual Studio y produzco una excepción con el mensaje "Bad credentials" en el método ServiceLogOn.

    Espero ver el cuadro de mensaje con la excepción.

    Pero Visual Studio detiene la aplicación de depuración y muestra una excepción en el método de servicio en el proyecto de servicio.

  2. Así que intento ejecutar WPF desde el archivo exe y producir la misma excepción en el método ServiceLogOn.

    me sale este error:

    excepción ha sido un tiro de destino de una invocación.

Cualquier excepción de la clase de vista del modelo no se maneja en métodos:

  • Application_DispatcherUnhandledException
  • o CurrentDomain_UnhandledException.

en la clase de la aplicación.

¿Qué hago mal?

EDITADO con la respuesta de Simon Fox.

Intento implementar el consejo de arranque de MEF de Simon Fox, pero todavía algo no funciona. Muevo la lógica del controlador para la excepción al método OnUnhandledException en la clase bootstraper.

Aquí está mi código de la clase bootstraper:

public class MefBootStrapper : Bootstrapper<IShellViewModel> 
    { 
//... 
    private IMessageBox _msgBox = new MessageBoxes.MessageBoxes(); 

    public bool DoHandle { get; set; } 

    protected override void OnUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e) 
    { 
     if (DoHandle) 
     { 
      _msgBox.ShowException(e.Exception); 
      e.Handled = true; 
     } 
     else 
     { 
      _msgBox.ShowException(e.Exception); 
      e.Handled = false; 
     } 

    } 
//... 
    } 

Ato algún método de vista del modelo en el botón y tirar nueva excepción. Algo como esto:

public void LogOn() 
{ 
    throw new ArgumentException("Bad argument"); 
} 

Pero el resultado es sam, pruebo la aplicación de Visual Studio y obtengo esta excepción.

Se ha lanzado una excepción por objetivo de una invocación.

+0

¿La Excepción tiene una InnerException? Si es así, ¿qué es? ¿Puedes publicar el StackTrace contenido en la excepción? –

+0

Hola Simón, la excepción interna es nula, si verifico en Visual Studio, el código en el método OnUnhandledException es una nota ejecutada. –

+0

Simon hago una muestra simple, si quieres puedes probar ut. Aquí está: http: //cid-042424ddb4d5fcbf.office.live.com/self.aspx/MSDN/MVVM%5E_and%5E_global%5E_exceptions%5E_handling.7z –

Respuesta

13

Caliburn.Micro ha incorporado soporte para enganchar excepciones no controladas. La clase Bootstrapper (que requiere cada proyecto de Caliburn) configura esto para usted y proporciona el método virtualOnUnhandledException.

en su aduana BootStrapper debe overrideOnUnhandledException para llevar a cabo las acciones personalizadas para las excepciones no controladas en su aplicación. Tenga en cuenta que lo más probable es que tenga que ordenar acciones como mostrar un cuadro de mensaje en el hilo de la interfaz de usuario (Caliburn lo habilita fácilmente a través del Execute.OnUIThread).

También puede haber un problema en la forma en que su servicio mueve las excepciones al cliente, pero sin ningún detalle de cómo se implementa el servicio/alojado/etc. No puedo ayudarlo. ¿Estás usando WCF para hacer SOAP? ¿Estás usando FaultContracts?

+0

Hola Simon, no estoy usando SOAP o REST Servicios web, es solo comunicación HTTP POST/GET, no SOAP/JSON. Edité mi pregunta, lo veo. –

+0

Esta respuesta es correcta. Sin embargo, no funcionó para mí, ya que la excepción no se lanzó desde el hilo de la interfaz de usuario. Estaba usando 'Task's así que me derivé de esta respuesta sugiriendo el uso de [Task.ContinueWith] (http://stackoverflow.com/a/7297904/448232) –

Cuestiones relacionadas