我正在开发一个应用程序,它应该通过套接字接口接收命令,然后在 GUI 中执行它们。该应用程序正在 C# .NET 4.0 中开发,并使用 WPF 作为其 GUI。
套接字接口有一个工作线程,它不断侦听套接字并处理其命令,因此,如果收到“显示弹出窗口”命令,则工作线程会调用一个管理器类,该管理器类负责创建弹出窗口并将其显示在主屏幕上。
创建弹出窗口然后调用主屏幕的管理器方法如下:
public void ProcessPopup(PopupModel model)
{
switch (model.ScreenType)
{
case Screens.Type1:
popup = new PopupType1();
break;
case Screens.Type2:
popup = new PopupType2();
break;
case Screens.Type3:
popup = new PopupType3();
break;
case Screens.Type4:
popup = new PopupType4();
break;
}
viewModel.SetModel(model);
if (!Dispatcher.CurrentDispatcher.Equals(App.Current.Dispatcher))
{
App.Current.Dispatcher.Invoke((ThreadStart)delegate { mainScreen.ShowPopup(popup); });
}
else
{
mainScreen.ShowPopup(popup);
}
}
PopupType1 类是:
public partial class PopupType1 : UserControl
{
public PopupType1 ()
{
InitializeComponent();
}
}
问题是,当我创建新的 Popup Type 1 对象时,出现以下异常:
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.InputManager.get_Current()
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.Controls.UserControl..ctor()
at MyApp.Views.PopupType1..ctor()
at MyApp.Manager.ProcessPopup(PopupModel model)
at MyApp.CommunicationController.ProcessAsync(XDocument messageXml)
我已经尝试过几种方法,例如将工作线程转换为 STA 线程,或者创建一个新的 STA 线程来处理 Popup 的创建,但它们造成的问题比解决的问题还要多。
最后值得一提的是,我正在这样做,因为我的应用程序在运行过程中遇到了几次“冻结”,我相信它们与 WPF GUI 线程因任务过多而无法正确响应这一事实有关,因此我试图将非 GUI 处理与 GUI 线程分开。