pondělí 28. listopadu 2011

WPF - Každé okno v aplikaci má vlastní vlákno - STA = Single threaded apartments, MTA = Multi-Threaded Apartments

Ve chvíli, kdy založíte nový projekt ve Visual Studio, vygeneruje se vám základní kostra aplikace. Která podle typu projektu WinForm nebo WPF vytvoří vstupní bod aplikace.

WinForm - funkce main
WPF - funkce main je skrytá, ale je možné ji přetížit a napsat si vlastní

Funkce main je vstupním bodem aplikace a je prováděna v hlavním vlákně aplikace (MainThread). Toto vlákno je nastaveno jako STA - Single thread apartments. Každé okno, které vytvoříme v aplikaci běží v rámci toho STA (kontejnéru na vlákna). Pokud budeme chtít vytvořit jiné vlákno, které bude provádět nějakou činnost, tak toto vlákno má nastaven apartments na MTA (multi-thread apartments). Data z tohoto vlákna můžeme synchronizovat do okna aplikace pomocí dispečeru.

myThread = new Thread(new ThreadStart(Execute));
myThread.Start();

V tomto vlákně máme nějaká omezení. Nemůžeme v něm vytvářet okna, ovládací prvky atd. Pokud chcete vytvořit nové okno v rámci jiného vlákna než je hlavní vlákno aplikace, vytvořte nové vlákno, ale nastavte mu apartments na STA.

myThread = new Thread(new ThreadStart(Execute));
myThread.Name = "Thread";
myThread.SetApartmentState(ApartmentState.STA);
myThread.IsBackground = true;
myThread.Start();

Nyní máme vytvořeno okno, ve kterém můžeme vytvořit nezávislé okno, ale aby okno fungovalo, musíme v rámci tohoto vlákna spustit dispečeram který se bude starat o případné synchronizace s jinými vlákny. Bez dispečera nebude okno fungovat.

oid Execute()
{
  MyWindow win = new MyWindow();
  win.Show();

  System.Windows.Threading.Dispatcher.Run();
}

Nezávislé okno máme hotovo.

Závěr
Hledal jsem příčinu, proč jsou takto pod .NETem vlákna řešena. Toto řešení se mi zdálo zbytečně komplikované. Ve většině článků bylo odůvodnění, že je to z důvodů zpětné kompatibility s COM objekty. Do hlubšího zkoumání jsem se už nepouštěl!

Žádné komentáře: