2013-10-25 55 views
3

我目前有一個AppDomain.CurrentDomain.UnhandledException處理程序,它在應用程序崩潰時通過電子郵件向我發送堆棧跟蹤。這在大多數情況下都可以正常工作,但是當我在MVVM light viewmodel中遇到異常時,堆棧跟蹤可能相當神祕,而不是真的告訴我它們在哪裏發生。有沒有簡單的方法來包裝我的視圖模型在try catch語句中,然後我可以在異常中注入更多有用的信息,然後重新拋出它?如何在try catch語句中包裝MVVM Light ViewModel?

以下是堆棧跟蹤的一個示例:

 
    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() 

這是通過一個NotImplementedException在我的視圖模型的方法,其被包裹在一個RelayCommand所以我可以一個按鈕綁定到它引起的。沒有什麼我可以弄清楚,這就指向了方法的名稱或視圖模型的名稱。

+1

你能展示一個神祕的例外嗎? –

+0

已添加堆棧跟蹤。我編輯的唯一東西是他的名字和我的應用程序的名稱以及其中包含整個項目路徑的行。 – PlTaylor

+0

這個異常是否有'InnerException'? –

回答

6

你應該有更多的信息在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); 
} 

這種方法是有幫助的,因爲往往你的情況下有3或其中4安葬真正的例外TargetInvocationException多個級別。

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

當然,這有可能會比較大,如果你有很多視圖模型您的信息,但我相信你可以找到一個更有效的方法來做到這一點。

+0

堆棧跟蹤沒有跡象表明它來自哪個視圖模型。 – PlTaylor