MVVM中的全局异常处理
本文关键字:异常处理 全局 MVVM | 更新日期: 2023-09-27 18:13:12
是否有办法实现MVVM模式的全局异常处理。在我现有的情况下,无论何时ViewModel内部发生错误,应用程序都不会崩溃,只是"隐藏"了在导致错误的代码之后发生的其余绑定(当然这对最终用户来说是非常误导的,并且不正确,并且不应该以这种方式发生)。我不想为viewModel中的每个操作实现try catch,我不喜欢错误异常的沉默方式,我真的很想实现一种WPF应用程序处理全局错误的方式。有办法做到这一点与MVVM吗?
经过长时间的战斗,我终于找到了一种非常简单的方法来实现ViewModel内部的异常处理。虽然创建从DefaultTraceListener继承的BindingListener当然是在调试模式中发现绑定错误的好方法,但这将无法捕获在标准模式下运行解决方案时在ViewModel中发生的异常。但是AppDomain.CurrentDomain.FirstChanceException会。
App.xaml.cs:
AppDomain.CurrentDomain.FirstChanceException += new EventHandler<System.Runtime.ExceptionServices.FirstChanceExceptionEventArgs>(CurrentDomain_FirstChanceException);
private void CurrentDomain_FirstChanceException(object sender, FirstChanceExceptionEventArgs e)
{
Dispatcher.BeginInvoke(new Action(() => MessageBox.Show("Error Occurred 'n'r" + e.Exception.Message + "'n'r" + e.Exception.StackTrace, "ERROR", MessageBoxButton.OK, MessageBoxImage.Error)));
}
您可以将每个方法包装在一个lambda中。像这样…
public async void DoSomething()
{
await RunSafe(async () =>
{
await model.DoSomething();
await model.DoSomethingElse();
await model.DoLastThing();
});
}
private async Task RunSafe(Func<Task> del, [CallerMemberName] String methodName = "")
{
try
{
Log.Info("Executing {0}", methodName);
await del();
}
catch (Exception ex)
{
StatusMessage = string.Format("Error in {0}(...): {1}'r'n{2}", methodName, ex.Message, ex.ToString());
Log.Error("Error occured in plug in.", ex);
}
}
考虑派生DefaultTraceListener
类。我看到有人从它派生出自己的BindingListener
,并覆盖WriteLine
方法来抛出自己的异常。
你可以在应用程序启动时启动其中一个,它应该自己运行:
public class BindingListener : DefaultTraceListener`
{
public BindingListener()
{
PresentationTraceSources.Refresh();
PresentationTraceSources.DataBindingSource.Listeners.Add(this);SourceLevels.Error;
}
public override void WriteLine(string message){...}
}
注意:这个可能不完全是你想要的,你可能需要修改一些道具