2014-01-24 4 views
0

У меня есть приложение WPF, как это:STA резьб исключение в приложении WPF

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; 

       } 
      } 

     } 

В методе Verifing я хотел бы создать экземпляр User Control

_3DCAO.Settings set = new Settings(); 

Но появляется эта ошибка:

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

  1. Зачем возникает это исключение?
  2. Как я могу это исправить?
+1

Взгляните на этот связанный пост. http://stackoverflow.com/questions/2329978/the-calling-thread-must-be-sta-because-many-ui-components-require-this – Jason

ответ

1

WPF (на самом деле все взаимодействия с Windows GUI) должен иметь любое взаимодействие с GUI в одном потоке графического интерфейса, поскольку GDI (подсистема, которая имеет дело с графическим интерфейсом в Windows) является однопоточной. Все должно быть в этой теме. Эта нить также является потоком STA.

Вы меняете контейнер, устанавливая его Контент, и делаете это неправильно. Есть способы довести его до нужной нити.

В конструкторе или после вызова InitializeComponents(), добавьте этот

this.guiContext = SynchronizationContext.Current; 

..where guiContext имеет тип System.Threading.SynchronizationContext. Вы можете отгрузку работы на GUI поток:

guiContext.Send(this.OnGuiThread, temp); 

Где OnGuiThread является методом, принимающим в качестве параметра объекта и температур является объектом послал к нему.

Это будет означать повторную организацию вашего кода, так как вам не только нужно создавать объекты GUI (например, «set» в вашем коде) в потоке, вы можете изменять их только в этом потоке.

Cheers -