首页 文章

如何在try catch语句中包装MVVM Light ViewModel?

提问于
浏览
3

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

以下是堆栈跟踪的示例:

at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
   at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
   at GalaSoft.MvvmLight.Helpers.WeakAction.Execute() in d:\GalaSoft\mydotnet\MvvmLight\Source\GalaSoft.MvvmLight\GalaSoft.MvvmLight (NET35)\Helpers\WeakAction.cs:line 269
   at GalaSoft.MvvmLight.Command.RelayCommand.Execute(Object parameter) in d:\GalaSoft\mydotnet\MvvmLight\Source\GalaSoft.MvvmLight\GalaSoft.MvvmLight (NET35)\Command\RelayCommand.cs:line 167
   at MS.Internal.Commands.CommandHelpers.CriticalExecuteCommandSource(ICommandSource commandSource, Boolean userInitiated)
   at System.Windows.Controls.Primitives.ButtonBase.OnClick()
   at System.Windows.Controls.Button.OnClick()
   at System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(MouseButtonEventArgs e)
   at System.Windows.UIElement.OnMouseLeftButtonUpThunk(Object sender, MouseButtonEventArgs e)
   at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
   at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
   at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
   at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
   at System.Windows.UIElement.ReRaiseEventAs(DependencyObject sender, RoutedEventArgs args, RoutedEvent newEvent)
   at System.Windows.UIElement.OnMouseUpThunk(Object sender, MouseButtonEventArgs e)
   at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
   at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
   at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
   at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
   at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
   at System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args)
   at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted)
   at System.Windows.Input.InputManager.ProcessStagingArea()
   at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)
   at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)
   at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel)
   at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
   at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
   at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
   at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
   at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
   at System.Windows.Threading.Dispatcher.Run()
   at System.Windows.Application.RunDispatcher(Object ignore)
   at System.Windows.Application.RunInternal(Window window)
   at System.Windows.Application.Run(Window window)
   at System.Windows.Application.Run()
   at MyApplication.App.Main() in c:|my computer\my projectname\obj\x86\Debug\App.g.cs:line 0
   at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
   at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
   at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
   at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()

这是由我的viewmodel中的一个方法中的 NotImplementedException 引起的,该方法包含在_1489594中,所以我可以将一个按钮绑定到它 . 我无法弄清楚是什么让我知道方法的名称或viewmodel的名称 .

2 回答

  • 0

    您应该在 InnerException 属性中有更多信息 .

    如果我没有弄错,你的主要例外是 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个 .

  • 6

    如果您已经处理了 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);
            }
        }
    }
    

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

相关问题