我一直在嘗試將現有的C#WPF API與Java應用程序進行接口。在Java應用程序中使用WPF庫時的線程問題?
到目前爲止,我已經成功使用jni4net來生成Java和.NET代碼之間接口的代理。
這種整合生產STA線程問題與正在顯示的WPF UI的:
System.InvalidOperationException: The calling thread must be STA, because many UI components require this.
at System.Windows.Input.InputManager..ctor()
at System.Windows.Input.InputManager.GetCurrentInputManagerImpl()
at System.Windows.Input.KeyboardNavigation..ctor()
at System.Windows.FrameworkElement.FrameworkServices..ctor()
at System.Windows.FrameworkElement.EnsureFrameworkServices()
at System.Windows.FrameworkElement..ctor()
at System.Windows.Controls.Control..ctor()
at System.Windows.Window..ctor()
這是通過使用以下模式加載的WPF UI的使用ShowDialog的克服:但是現在
Thread thread = new Thread(new ParameterizedThreadStart(ParameterizedMethodName));
thread.SetApartmentState(ApartmentState.STA);
thread.Start(parameter);
thread.Join();
,在使用WPF UI時,我遇到類似於以下的異常,鼠標單擊或按鍵可觸發以下內容(此示例來自於鼠標單擊):
System.InvalidOperationException: The calling thread cannot access this object because a different thread owns it.
at System.Windows.Threading.Dispatcher.VerifyAccess()
at System.Windows.DependencyObject.GetValue(DependencyProperty dp)
at System.Windows.Input.InputBinding.get_Command()
at System.Windows.Input.InputBindingCollection.FindMatch(Object targetElement, InputEventArgs inputEventArgs)
at System.Windows.Input.CommandManager.TranslateInput(IInputElement targetElement, InputEventArgs inputEventArgs)
at System.Windows.UIElement.OnMouseDownThunk(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.InvokeImpl(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.Window.ShowHelper(Object booleanBox)
at System.Windows.Window.Show()
at System.Windows.Window.ShowDialog()
我目前不確定如何解決此問題並從堆棧跟蹤中確定問題的原因。
任何幫助/意見是非常感謝。
謝謝。我已經意識到使用CheckAccess()並且已經爲此寫了一個擴展方法。唯一的問題是我不知道從哪裏開始測試!來自異常的堆棧跟蹤並不指向我的問題的方向,因爲它是一個.NET堆棧跟蹤... – Paul
我不認爲它真的很重要,找到WPF API調用ShowDialog()的任何地方, '並確保它是線程安全的。你需要這樣做,否則你最終會修復這個特定的錯誤,然後運行到另一個,另一個,另一個。 – CodingGorilla
即使使用CheckAccess()和BeginInvoke()包裝了ShowDialog(),我仍然在主WPF UI上遇到同樣的異常。 – Paul