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

时间:2019-01-24 20:04:32

标签: c# wpf exception-handling prism prism-6

我有一个Prism WPF应用程序,该应用程序在部署时无法加载其模块之一(由于数据库问题)。在我的开发机器上,我可以在Visual Studio的“输出”窗口中看到抛出的相关异常(显然是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记录应用程序中引发的异常?

2 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分:0)

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...");
  

但是它仍然不会记录我的应用程序中引发的任何异常

我建议在Dispatcher.UnhandledException内添加App.xaml.cs,这样无论哪里发生未处理的异常,都将在此结束。

   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类或其他库。 我只是看不到其他解决方案。

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);
        }

    }
}