3

我目前有一个AppDomain.CurrentDomain.UnhandledException处理程序,当应用程序崩溃时,它会通过电子邮件向我发送堆栈跟踪。这在大多数情况下都可以正常工作,但是当我在 MVVM 轻视图模型中遇到异常时,堆栈跟踪可能相当神秘,并不能真正告诉我它们发生在哪里。有没有一种简单的方法可以将我的视图模型包装在 try catch 语句中,然后我可以将一些更有用的信息注入异常,然后重新抛出它?

以下是堆栈跟踪的示例:

   在 System.RuntimeMethodHandle.InvokeMethod(对象目标,对象 [] 参数,签名 sig,布尔构造函数)
   在 System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(对象 obj,对象 [] 参数,对象 [] 参数)
   在 System.Reflection.RuntimeMethodInfo.Invoke(Object obj,BindingFlags invokeAttr,Binder binder,Object[] 参数,CultureInfo 文化)
   在 System.Reflection.MethodBase.Invoke(对象 obj,对象 [] 参数)
   在 d:\GalaSoft\mydotnet\MvvmLight\Source\GalaSoft.MvvmLight\GalaSoft.MvvmLight (NET35)\Helpers\WeakAction.cs:line 269 中的 GalaSoft.MvvmLight.Helpers.WeakAction.Execute()
   在 d:\GalaSoft\mydotnet\MvvmLight\Source\GalaSoft.MvvmLight\GalaSoft.MvvmLight (NET35)\Command\RelayCommand.cs:line 167 中的 GalaSoft.MvvmLight.Command.RelayCommand.Execute(对象参数)
   在 MS.Internal.Commands.CommandHelpers.CriticalExecuteCommandSource(ICommandSource commandSource,Boolean userInitiated)
   在 System.Windows.Controls.Primitives.ButtonBase.OnClick()
   在 System.Windows.Controls.Button.OnClick()
   在 System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(MouseButtonEventArgs e)
   在 System.Windows.UIElement.OnMouseLeftButtonUpThunk(对象发送者,MouseButtonEventArgs e)
   在 System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(委托 genericHandler,对象 genericTarget)
   在 System.Windows.RoutedEventArgs.InvokeHandler(委托处理程序,对象目标)
   在 System.Windows.RoutedEventHandlerInfo.InvokeHandler(对象目标,RoutedEventArgs routedEventArgs)
   在 System.Windows.EventRoute.InvokeHandlersImpl(对象源,RoutedEventArgs args,布尔 reRaised)
   在 System.Windows.UIElement.ReRaiseEventAs(DependencyObject 发件人,RoutedEventArgs 参数,RoutedEvent newEvent)
   在 System.Windows.UIElement.OnMouseUpThunk(对象发送者,MouseButtonEventArgs e)
   在 System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(委托 genericHandler,对象 genericTarget)
   在 System.Windows.RoutedEventArgs.InvokeHandler(委托处理程序,对象目标)
   在 System.Windows.RoutedEventHandlerInfo.InvokeHandler(对象目标,RoutedEventArgs routedEventArgs)
   在 System.Windows.EventRoute.InvokeHandlersImpl(对象源,RoutedEventArgs args,布尔 reRaised)
   在 System.Windows.UIElement.RaiseEventImpl(DependencyObject 发件人,RoutedEventArgs 参数)
   在 System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs 参数)
   在 System.Windows.UIElement.RaiseEvent(RoutedEventArgs 参数,布尔值信任)
   在 System.Windows.Input.InputManager.ProcessStagingArea()
   在 System.Windows.Input.InputManager.ProcessInput(InputEventArgs 输入)
   在 System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)
   在 System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd,InputMode 模式,Int32 时间戳,RawMouseActions 动作,Int32 x,Int32 y,Int32 轮)
   在 System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd,WindowMessage msg,IntPtr wParam,IntPtr lParam,布尔&处理)
   在 System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd,Int32 msg,IntPtr wParam,IntPtr lParam,Boolean& 处理)
   在 MS.Win32.HwndWrapper.WndProc(IntPtr hwnd,Int32 msg,IntPtr wParam,IntPtr lParam,Boolean& 处理)
   在 MS.Win32.HwndSubclass.DispatcherCallbackOperation(对象 o)
   在 System.Windows.Threading.ExceptionWrapper.InternalRealCall(委托回调,对象 args,Int32 numArgs)
   在 MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(对象源,委托方法,对象 args,Int32 numArgs,委托 catchHandler)
   在 System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority 优先级,TimeSpan 超时,委托方法,对象 args,Int32 numArgs)
   在 MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd,Int32 msg,IntPtr wParam,IntPtr lParam)
   在 MS.Win32.UnsafeNativeMethods.DispatchMessage(味精和味精)
   在 System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame 框架)
   在 System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame 框架)
   在 System.Windows.Threading.Dispatcher.Run()
   在 System.Windows.Application.RunDispatcher(对象忽略)
   在 System.Windows.Application.RunInternal(窗口窗口)
   在 System.Windows.Application.Run(窗口窗口)
   在 System.Windows.Application.Run()
   在 c:|my computer\my projectname\obj\x86\Debug\App.g.cs:line 0 中的 MyApplication.App.Main()
   在 System.AppDomain._nExecuteAssembly(RuntimeAssembly 程序集,字符串 [] 参数)
   在 System.AppDomain.ExecuteAssembly(字符串 assemblyFile,证据 assemblySecurity,String [] args)
   在 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
   在 System.Threading.ThreadHelper.ThreadStart_Context(对象状态)
   在 System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext,ContextCallback 回调,对象状态,布尔值 preserveSyncCtx)
   在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback 回调,对象状态,布尔值 preserveSyncCtx)
   在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback 回调,对象状态)
   在 System.Threading.ThreadHelper.ThreadStart()

这是由NotImplementedException我的视图模型中的一个方法引起的,该方法包含在一个中,RelayCommand因此我可以将一个按钮绑定到它。没有什么可以让我指出方法的名称或视图模型的名称。

4

2 回答 2

6

你应该有更多的InnerException财产信息。

如果我没记错的话,你的主要例外是 type TargetInvocationException。你可以写一个小方法来解开这个:

public Exception Unwrap(TargetInvocationException root)
{
    if(root.InnerException == null)
        return root;
    var innerException = root.InnerException as TargetInvocationException;
    if(innerException == null)
        return root.InnerException;

    return Unwrap(innerException);
}

此方法很有帮助,因为您通常有多个级别,TargetInvocationException而真正的异常隐藏在其中的 3 或 4 个之下。

于 2013-10-25T15:16:16.447 回答
0

如果您已经在处理该AppDomain.CurrentDomain.UnhandledException事件,是否可以不在该处理程序中添加您的信息?:

public void MainWindow_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
    Exception exception = (Exception)e.ExceptionObject;
    if (exception.TargetSite.Module.ToString() == "nameOfViewModelAssembly.dll")
    {
        if (exception.StackTrace.Contains(nameOfSomeViewModel))
        {
            throw new Exception("Problem in nameOfSomeViewModel", exception);
        }
        else if (exception.StackTrace.Contains(nameOfOtherViewModel))
        {
            throw new Exception("Problem in nameOfOtherViewModel", exception);
        }
    }
}

当然,如果您有很多视图模型,这可能会变得非常大,但我相信您可以找到一种更有效的方法来做到这一点。

于 2013-10-25T14:53:26.577 回答