Я пытаюсь связать существующий API C# WPF с приложением Java.Проблемы с потоками при использовании библиотеки WPF в Java-приложении?
До сих пор я успешно использовал 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, щелчок мышью или нажатие клавиши может вызвать следующее (этот пример был нажатием мыши):
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
Я по-прежнему испытываю такое же исключение в своем основном WPF-интерфейсе, даже если ShowDialog() завернут CheckAccess() и BeginInvoke(). – Paul