Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在java应用程序中使用WPF库时的线程问题?_C#_Java_Wpf_Thread Safety_Jni4net - Fatal编程技术网

C# 在java应用程序中使用WPF库时的线程问题?

C# 在java应用程序中使用WPF库时的线程问题?,c#,java,wpf,thread-safety,jni4net,C#,Java,Wpf,Thread Safety,Jni4net,我一直在尝试将现有的C#WPF API与Java应用程序进行接口 到目前为止,我已经成功地用于生成Java和.NET代码之间接口的代理 此集成在显示WPF UI时产生了STA线程问题: System.InvalidOperationException: The calling thread must be STA, because many UI components require this. at System.Windows.Input.InputManager..ctor() a

我一直在尝试将现有的C#WPF API与Java应用程序进行接口

到目前为止,我已经成功地用于生成Java和.NET代码之间接口的代理

此集成在显示WPF UI时产生了STA线程问题:

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的using ShowDialog,可以克服这一问题:

Thread thread = new Thread(new ParameterizedThreadStart(ParameterizedMethodName));
thread.SetApartmentState(ApartmentState.STA);
thread.Start(parameter);
thread.Join();
然而,现在我在使用WPF UI时遇到了与以下类似的异常,鼠标单击或按键可触发以下事件(此示例来自鼠标单击):

我目前不确定如何解决此问题,并从堆栈跟踪中确定问题的原因


非常感谢您提供的任何帮助/建议。

关于解决方案,我不能提供太多建议,但我可以告诉您问题所在。所有WPF代码必须在同一线程上运行(可能是您正在创建的线程)。您收到的错误是因为有人试图从其他线程访问WPF控件

假设有一个显示对话框的API调用,java代码调用
MyApi.ShowDialog
。您的API
ShowDialog
方法不能简单地调用
MyDialog.ShowDialog()
,因为对UI组件的调用将来自java线程。相反,您的API需要足够智能,以便将这些调用封送到适当的WPF(UI)线程

所以它应该做一些类似的事情:

if(!CheckAccess())
    MyDialog.Dispatcher.BeginInvoke(DeleageToShowDialog);

不幸的是,这可能意味着您必须在API上做大量工作,因为它可能无法解决此类线程问题。

谢谢。我已经知道如何使用CheckAccess(),并且已经为此编写了一个扩展方法。唯一的问题是我不知道从哪里开始测试!异常中的堆栈跟踪没有指向问题的方向,因为它是.NET堆栈跟踪…我认为这并不重要,请在WPF API中找到调用
ShowDialog()
的任何位置,并确保它是线程安全的。您需要这样做,否则最终会修复此特定错误,然后遇到另一个、另一个、另一个。即使ShowDialog()使用CheckAccess()和BeginInvoke()包装,我的主WPF UI上仍会遇到相同的异常。很抱歉,我无法提供更多帮助,但潜在的问题是,您必须确保对WPF UI的任何访问都只能从创建UI的线程进行。我敢肯定,这将是一个很难解决的问题,因为跨线程访问有时会非常微妙,但对于问题是什么,例外情况非常清楚。感谢您的帮助,尽管我将研究集成此代码的不同方向。我没有提到的一点是,当通过COM与不同的应用程序集成时,该代码能够成功地工作。由于将COM与Java应用程序集成的类似问题,我只切换到JNI4NET。
if(!CheckAccess())
    MyDialog.Dispatcher.BeginInvoke(DeleageToShowDialog);