I am developing an application that should receive commands through a socket interface and then execute them in a GUI. This application is being developed in C# .NET 4.0 and it uses WPF for its GUI.
The socket interface has a worker thread that keeps listening to the socket and processing its commands, so if for example a Show Popup command is received, the worker thread calls a manager class that is responsible for creating the popup and showing it on the main screen.
The manager method that creates the popup and then calls the main screen is the following:
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);
}
}
The class PopupType1 is:
public partial class PopupType1 : UserControl
{
public PopupType1 ()
{
InitializeComponent();
}
}
The problem is that when I craete a new PopupType1 object I get the following exception:
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)
I've tried several things already like transforming my worker thread into a STA thread, or creating a new STA thread just to handle the creation of the Popup, but they caused more problems than they solved.
Finally it is important to mention that I am doing this, because my application is experiencing several "freezes" during its operation and I believe that they are related to the fact that the WPF GUI thread is too overwhelmed with tasks to be properly responsive, therefore I am trying to separate the non-GUI processing from the GUI thread.
You need to create the UI control on the UI thread as well. So basically all of ProcessPopup needs to be executed on the UI thread in your case and not just mainScreen.ShowPopup()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With