سؤال

I have a wpf application like this :

public CreateProject()
        {
            InitializeComponent();
            _3DCAO.Temporary3DCAO.Close = false;
            Userinitial fen = new Userinitial();
            container.Content = fen;
            Thread windowThread2 = new Thread(delegate() { verifing2(); });
            windowThread2.IsBackground = true;
            windowThread2.Start();
        }
public void verifing2()
        {
            bool condition_accomplished = false;
            while (!condition_accomplished)
            {
                if (Temporary3DCAO.Etape == 1)
                {

                    _3DCAO.Settings set = new Settings();
                    if (container.Dispatcher.CheckAccess())
                    {

                        container.Content = set;
                    }
                    else
                    {

                        container.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() =>
                        {
                            container.Content = set;
                        }));

                    }
                    condition_accomplished = true;

                }
            }

        }

In the method Verifing i'd like to instanciate a User Control

_3DCAO.Settings set = new Settings();

But this error appears :

The calling thread must be STA, as required by many components of the user interface

  1. Why this exception appears?
  2. How can i fix it?
هل كانت مفيدة؟

المحلول

WPF (in fact all Windows GUI interactions) must have any GUI interaction on a single GUI thread, because the GDI (the subsystem which deals with the GUI in Windows) is single threaded. Everything must be on that thread. That thread is also an STA thread.

You're changing container, setting it's Content, and you're doing it on the wrong thread. There are ways to get it to the right thread.

In the constructor or after calling InitializeComponents(), add this

this.guiContext = SynchronizationContext.Current;

..where guiContext is of type System.Threading.SynchronizationContext. You can then despatch work onto the GUI thread:

guiContext.Send(this.OnGuiThread, temp);

Where OnGuiThread is a method taking as object parameter and temp is the object sent to it.

This will mean re-organising your code, as not only do you have to create GUI objects (like "set" in your code) on the thread, you can only change them on that thread.

Cheers -

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top