我如何让 Prism 报告它捕获的异常?

How do I get Prism to report the exceptions it traps?

我有一个 Prism WPF 应用程序,当我部署它时无法加载其中一个模块(由于数据库问题)。在我的开发机器上,我可以在 Visual Studio 的输出 window 中看到相关异常被抛出(显然被 Prism 捕获和处理)。

我这样做能够解决眼前的问题:

public MyModuleViewConstructor()
{
    try
    {
        // some startup work here
        // ...
        InitializeComponent();
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString(), "A System Error Occurred.");
    }
}

显示生产中的错误,以便我可以对其采取措施。但我仍然想从正常操作期间抛出的任何异常中获取消息,因此,本着 Prism 做事方式的精神,我这样做了:

public class Logger : ILoggerFacade
{
    public void Log(string message, Category category, Priority priority)
    {
        using (StreamWriter s = File.AppendText("Log.txt"))
        {
            s.WriteLine(string.Format("{0}-{1}: {2}", DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss.ffff"), priority.ToString(), message));
            s.Close();
        }
    }
}

并在 Bootstrapper 中注册:

class Bootstrapper : DryIocBootstrapper
{
    private readonly Logger _logger = new Logger();

    protected override ILoggerFacade CreateLogger()
    {
        return _logger;
    }
}

这对于调试日志记录等普通日志条目非常有效。 但它仍然没有记录我的应用程序中抛出的任何异常。

如何让 Prism 记录我的应用程序中抛出的异常?

Prism 日志记录机制主要用于记录与 Prism 事件相关的消息。 要将它用于您的活动,您可以像这样创建和扩展方法

 public static class LoggerExtensions
    {
        public static void Warn(this ILoggerFacade loger, string message)
        {
            using (StreamWriter s = File.AppendText("Log.txt"))
            {
                s.WriteLine(string.Format(" {0}-{1}: {2}", DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss.ffff"), Category.Warn, message));
                s.Close();
            }
        }
    }

要在您的代码中使用它,您可以执行以下操作

  var logger = _container.Resolve<ILoggerFacade>(); //If you use IoC
  LoggerExtensions.Warn(logger, "Some exception...");

But it still does not log any exceptions thrown within my application

我建议在App.xaml.cs里面加上Dispatcher.UnhandledException,这样哪里有异常没有处理,就到此结束。

   public partial class App : Application
    {
        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);
            this.Dispatcher.UnhandledException += OnDispatcherUnhandledException;
        }
        void OnDispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
        {
         //Your code
        }
    }

更新 #2 我创建了一个小示例,点击按钮将抛出 DivideByZeroException。 Prism 日志记录机制根本不知道这个异常。唯一的解决方案是使用扩展方法,扩展 Exception class 或其他库。 我只是看不到任何其他解决方案。

public partial class ViewA : UserControl
{
    ILoggerFacade logger;
    public ViewA(ILoggerFacade _logger)
    {
        InitializeComponent();
        logger = _logger;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        try
        {
            var val = 0;
            var result = 1500 / val;
        }
        catch (Exception ex)
        {
            LoggerExtensions.Warn(logger, ex.Message);
        }

    }
}

导航时,视图 and/or 视图模型创建期间发生的所有异常都被区域管理器捕获。默认情况下不会记录这些(尽管这将是一个很酷的功能)。

但是,您可以收到有关异常的通知并自行记录或以其他方式做出反应。

为此,请浏览 IRegionManager.RequestNavigate( ..., Action<NavigationResult> navigationCallback ) 重载之一。 navigationCallback 将传递一个结果对象,其中包含 NavigationResult.Error 属性 中的任何异常。