W dokumentacji .Net napisane jest jednoznacznie - jedynym wątkiem, który może wykonywać jakiekolwiek operacje na formatce (System.Windows.Forms.Form
) jest ten, który ją utworzył. Pozostałym wolno jedynie wywoływać metody z serii Invoke()
, które z kolei zaowocują wykonaniem podanego do nich delegate
w wątku formatki. A jak tego po ludzku użyć? Ano tak:
w klasie formatki
//sygnatura funkcji do wywołania z zewnątrz
delegate void SetTextDelegate(string text);
//i sama funkcja
void SetText(string text)
{
if(!InvokeRequired)//czyli wywołanie z wątku formatki
button1.Text = text;
else
Invoke(new SetTextDelegate(SetText), text);//trzeba zmienić wątek
}
natomiast użycie tego w wątku zewnętrznym to po prostu
form1.SetText((i*i).ToString());
Wersja 2.0 platformy umożliwia wykonanie tej samej operacji jeszcze prościej, mianowicie poprzez wywołanie
form1.Invoke((MethodInvoker)delegate { form1.button1.Text = (i * i).ToString(); });
Tutaj niepotrzebne są żadne dodatkowe metody w formatce, po prostu informujemy framework, że ten kawałek kodu ma być wykonany w wątku będącym właścicielem form1
. Jedynym haczykiem jest rzutowanie do MethodInvoker
. Jest ono konieczne, ponieważ metoda Invoke()
jako parametr przyjmuje dowolny System.Delegate
... który niestety sam nie jest typu delegate
. Bez MethodInvoker
metoda anonimowa byłaby rzutowana do System.Delegate
, co skończyłoby się błędem kompilacji. A w ten sposób kompilator rozumie o co nam chodzi.
Jeśli już wykorzystywałeś wątki razem z Windows.Forms
to pewnie zastanawiasz się, po co ta cała szopka, przecież można odwoływać się do formatki z innego wątku i wszystko działa? Ano działa, ale tylko na Windows XP. W tej wersji platformy .Net wprowadzono niestety zabezpiecznia przed najczęstszymi błędami związanymi z programowaniem wielowątkowym, co prowadzi do tego, iż da się na niej uruchomić kod niepoprawny, który nie zadziała np. na Windows 98 lub mono. Zresztą, w aktualnej (1.1.13.*) implementacji Windows.Forms
pod tym ostatnim jest parę innych problemów - np. tworzenie formatek (całkowicie niezależnych!) w kilku różnych wątkach prowadzi do niedeterministycznego zachowania programu i częstych padów...
No comments:
Post a Comment