Czasami używam (w Load)
this.BeginInvoke((MethodInvoker) delegate {
// some code
});
lub
this.BeginInvoke((MethodInvoker) this.SomeMethod);
(zmień „this” na swoją zmienną formularza, jeśli obsługujesz zdarzenie w instancji innej niż „this”).
To wypycha wywołanie do pętli Windows-Forms, więc jest przetwarzane, gdy formularz przetwarza kolejkę komunikatów.
[aktualizowane na żądanie]
Metody Control.Invoke / Control.BeginInvoke są przeznaczone do użytku z wątkami i są mechanizmem wypychania pracy do wątku interfejsu użytkownika. Zwykle jest to używane przez wątki robocze itp. Control.Invoke wykonuje wywołanie synchroniczne, podczas gdy Control.BeginInvoke wykonuje wywołanie asynchroniczne.
Zwykle byłyby używane jako:
SomeCodeOrEventHandlerOnAWorkerThread()
{
// this code running on a worker thread...
string newText = ExpensiveMethod(); // perhaps a DB/web call
// now ask the UI thread to update itself
this.Invoke((MethodInvoker) delegate {
// this code runs on the UI thread!
this.Text = newText;
});
}
Robi to poprzez wypychanie wiadomości do kolejki wiadomości systemu Windows; Wątek interfejsu użytkownika (w pewnym momencie) usuwa z kolejki wiadomość, przetwarza delegata i sygnalizuje pracownikowi, że zakończył pracę ... na razie tak dobrze ;-p
DOBRZE; więc co się stanie, jeśli użyjemy Control.Invoke / Control.BeginInvoke w wątku interfejsu użytkownika? Radzi sobie ... jeśli wywołasz Control.Invoke, rozsądnie jest wiedzieć, że blokowanie kolejki komunikatów spowodowałoby natychmiastowy zakleszczenie - więc jeśli jesteś już w wątku interfejsu użytkownika, po prostu natychmiast uruchamia kod ... więc nam nie pomaga ...
Ale Control.BeginInvoke działa inaczej: zawsze wypycha pracę do kolejki, nawet jeśli jesteśmy już w wątku interfejsu użytkownika. To naprawdę prosty sposób na powiedzenie „za chwilę”, ale bez niedogodności związanych z licznikami czasu itp. (Które i tak musiałyby robić to samo!).