2016-03-21 47 views
0

我們正在向我們的catel 4.4.0 MVVM應用程序添加第二個UI線程。在第二個UI線程上使用命令時出現InvalidOperationException

我在第二個UI線程上創建了我的視圖和視圖模型,並使用DispatcherTimer定期更新視圖模型。這部分似乎工作正常。但是,當我在視圖模型的構造函數中創建Catel.MVVM.Command時,我遇到了問題。當命令的CanExecute觸發時,我在第二個UI線程上收到一個System.InvalidOperationException異常。

該命令沒什麼特別的。

private bool ImageClickCanExecute() 
{ 
    return true; 
} 

public void ImageClickAction() 
{ 
    if(ImageClickTarget != null) 
     Process.Start(ImageClickTarget.ToString()); 
} 

該視圖不是。

<Grid> 
    <Button Command="{Binding ImageClickCommand}"> 
     <Image Name="ImageSource" Source="{Binding ImageSource, FallbackValue={x:Null}}"/> 
    </Button> 
</Grid> 

堆棧跟蹤如下。

0:010> !PrintException /d 00000282cb8effd0 
Exception object: 00000282cb8effd0 
Exception type: System.Reflection.TargetInvocationException 
Message:   Exception has been thrown by the target of an invocation. 
InnerException: System.InvalidOperationException, Use !PrintException 00000282cb8edee8 to see more. 
StackTrace (generated): 
    SP    IP    Function 
    000000B0459FD510 0000000000000000 mscorlib_ni!System.RuntimeMethodHandle.InvokeMethod(System.Object, System.Object[], System.Signature, Boolean)+0x1 
    000000B0459FD510 00007FFFCC5E1C20 mscorlib_ni!System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(System.Object, System.Object[], System.Object[])+0x80 
    000000B0459FD580 00007FFFCC5BE789 mscorlib_ni!System.Delegate.DynamicInvokeImpl(System.Object[])+0x99 
    000000B0459FD5D0 00007FFF70FC83AE UNKNOWN!Catel.EventHandlerExtensions.SplitInvoke(System.Delegate, System.Object[])+0xfe 
    000000B0459FD630 00007FFF7164E085 UNKNOWN!Catel.EventHandlerExtensions.SafeInvoke(System.EventHandler, System.Object, System.EventArgs)+0x55 
    000000B0459FD680 00007FFF71674998 UNKNOWN!Catel.MVVM.Command`2+<<RaiseCanExecuteChanged>b__32_0>d[[System.__Canon, mscorlib],[System.__Canon, mscorlib]].MoveNext()+0x38 
    000000B0459FD7B0 00007FFFCD2E1224 mscorlib_ni!System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(System.Threading.Tasks.Task)+0xd3f9c4 
    000000B0459FD7F0 00007FFFCC5A17AD mscorlib_ni!System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(System.Threading.Tasks.Task)+0x3d 
    000000B0459FD820 00007FFF71674515 UNKNOWN!Catel.MVVM.Command`2+<>c__DisplayClass35_0+<<AutoDispatchIfRequiredAsync>b__0>d[[System.__Canon, mscorlib],[System.__Canon, mscorlib]].MoveNext()+0xf5 
    000000B0459FD9B0 00007FFFCCFCDA88 mscorlib_ni!System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__6_0(System.Object)+0x38 
    000000B0459FD9E0 00007FFFA8119C0E WindowsBase_ni!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, System.Object, Int32)+0xae 
    000000B0459FDA50 00007FFFA8119AC6 WindowsBase_ni!System.Windows.Threading.ExceptionWrapper.TryCatchWhen(System.Object, System.Delegate, System.Object, Int32, System.Delegate)+0x36 
    000000B0459FDAA0 00007FFFA811CA2B WindowsBase_ni!System.Windows.Threading.DispatcherOperation.InvokeImpl()+0x10b 
    000000B0459FDB20 00007FFFCC5CA79E mscorlib_ni!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)+0x15e 
    000000B0459FDBF0 00007FFFCC5CA637 mscorlib_ni!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)+0x17 
    000000B0459FDC20 00007FFFCC5CA5F2 mscorlib_ni!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)+0x52 
    000000B0459FDC70 00007FFFA8333810 WindowsBase_ni!MS.Internal.CulturePreservingExecutionContext.Run(MS.Internal.CulturePreservingExecutionContext, System.Threading.ContextCallback, System.Object)+0x80 
    000000B0459FDCD0 00007FFFA811C784 WindowsBase_ni!System.Windows.Threading.DispatcherOperation.Invoke()+0x64 
    000000B0459FDD30 00007FFFA8117C24 WindowsBase_ni!System.Windows.Threading.Dispatcher.ProcessQueue()+0x1a4 
    000000B0459FDDB0 00007FFFA8118061 WindowsBase_ni!System.Windows.Threading.Dispatcher.WndProcHook(IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef)+0x71 
    000000B0459FDE30 00007FFFA8119E53 WindowsBase_ni!MS.Win32.HwndWrapper.WndProc(IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef)+0xc3 
    000000B0459FDEC0 00007FFFA8119D82 WindowsBase_ni!MS.Win32.HwndSubclass.DispatcherCallbackOperation(System.Object)+0x82 
    000000B0459FDF10 00007FFFA8119BC9 WindowsBase_ni!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, System.Object, Int32)+0x69 
    000000B0459FDF80 00007FFFA8119AC6 WindowsBase_ni!System.Windows.Threading.ExceptionWrapper.TryCatchWhen(System.Object, System.Delegate, System.Object, Int32, System.Delegate)+0x36 
    000000B0459FDFD0 00007FFFA8117583 WindowsBase_ni!System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority, System.TimeSpan, System.Delegate, System.Object, Int32)+0x173 
    000000B0459FE070 00007FFFA81194FF WindowsBase_ni!MS.Win32.HwndSubclass.SubclassWndProc(IntPtr, Int32, IntPtr, IntPtr)+0x11f 
    000000B0459FE390 0000000000000000 WindowsBase_ni!MS.Win32.UnsafeNativeMethods.DispatchMessage(System.Windows.Interop.MSG ByRef)+0x1 
    000000B0459FE450 00007FFFA812D8FC WindowsBase_ni!System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame)+0xec 
    000000B0459FE4E0 00007FFFA26A98B3 PresentationFramework_ni!System.Windows.Application.RunDispatcher(System.Object)+0x73 
    000000B0459FE520 00007FFFA26A969D PresentationFramework_ni!System.Windows.Application.RunInternal(System.Windows.Window)+0x8d 
    000000B0459FE580 00007FFF70FD70F7 UNKNOWN!xxx.Wpf.App.Main()+0x67 
    000000B0459FF0C0 0000000000000000 mscorlib_ni!System.AppDomain._nExecuteAssembly(System.Reflection.RuntimeAssembly, System.String[])+0x1 
    000000B0459FF0C0 00007FFFCCD57EBF mscorlib_ni!System.AppDomain.ExecuteAssembly(System.String, System.Security.Policy.Evidence, System.String[])+0x7f 
    000000B0459FF110 00007FFF7053434E UNKNOWN!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()+0x3e 
    000000B0459FF150 00007FFFCC5CA79E mscorlib_ni!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)+0x15e 
    000000B0459FF220 00007FFFCC5CA637 mscorlib_ni!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)+0x17 
    000000B0459FF250 00007FFFCC5CA5F2 mscorlib_ni!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)+0x52 
    000000B0459FF2A0 00007FFFCC51BEF2 mscorlib_ni!System.Threading.ThreadHelper.ThreadStart()+0x52 

StackTraceString: <none> 
HResult: 80131604 
0:010> !PrintException /d 00000282cb8edee8 
Exception object: 00000282cb8edee8 
Exception type: System.InvalidOperationException 
Message:   The calling thread cannot access this object because a different thread owns it. 
InnerException: <none> 
StackTrace (generated): 
    SP    IP    Function 
    000000B0459FCD70 00007FFFA8446977 WindowsBase_ni!System.Windows.Threading.Dispatcher.VerifyAccess()+0x32faf7 
    000000B0459FCDA0 00007FFFA8112806 WindowsBase_ni!System.Windows.DependencyObject.GetValue(System.Windows.DependencyProperty)+0x26 
    000000B0459FCE00 00007FFFA27EBB5B PresentationFramework_ni!System.Windows.Controls.Primitives.ButtonBase.get_Command()+0x2b 
    000000B0459FCE30 00007FFFA27EBB00 PresentationFramework_ni!System.Windows.Controls.Primitives.ButtonBase.UpdateCanExecute()+0x10 

StackTraceString: <none> 
HResult: 80131509 

回答

0

這是因爲,默認情況下,這些命令會自動使用DispatcherService發送更改通知。由於您正在運行邊緣案例場景(2個線程),因此我建議您關閉自動調度並自行處理。

由於這是一個靜態保護成員,因此您需要從CommandBase派生自己的命令類,並將AutomaticallyDispatchEvents設置爲false

ps。我建議使用IProcessService而不是直接使用Process.Start,它允許您嘲笑它或在需要時替換它。

+1

其實AutomaticallyDispatchEvents可以在catel 4.4.0中使用。我將其設置爲false,它確實解決了我的問題。 – JonDrnek

相關問題