2009-04-23 9 views
26

Korzystając z C# 2.0 i delegata MethodInvoker, mam aplikację GUI odbierającą pewne zdarzenie z wątku GUI lub wątku roboczego.Korzystanie z C# MethodInvoker.Invoke() dla aplikacji GUI ... czy to jest dobre?

używam następujący wzór dla obsługi zdarzeń w formie:

private void SomeEventHandler(object sender, EventArgs e) 
{ 
    MethodInvoker method = delegate 
     { 
      uiSomeTextBox.Text = "some text"; 
     }; 

    if (InvokeRequired) 
     BeginInvoke(method); 
    else 
     method.Invoke(); 
} 

Stosując ten schemat nie powielać rzeczywisty kod UI ale co nie jestem pewien, czy jest to metoda jest dobra .

W szczególności, linia

method.Invoke() 

to użyć innego wątku powołując czy też tłumaczyć nieco do bezpośredniego wywołania metody na wątków GUI?

Odpowiedz

21

Wywołanie method.Invoke() wykonuje delegata w bieżącym wątku wykonywania. Korzystanie z BeginInvoke(method) zapewnia wywołanie delegata w wątku GUI.

Jest to poprawny sposób uniknięcia duplikacji kodu, gdy ta sama metoda może zostać wywołana zarówno z wątku GUI i innych wątków.

+0

Dzięki! Utknąłem przy użyciu metody. Invoke, a nawet Invoke ((MethodInvoker) Wracając do BeginInvoke, poradził sobie. –

0

Umożliwia wywoływanie w tym samym wątku. Możesz sprawdzić, przechodząc przez kod. Nie ma nic złego w tym podejściu.

2

Dla WinForms wywołanie Control.Invoke(Delegate) powoduje wysłanie wiadomości do pompy komunikatów thead's message. Wątek przetwarza następnie wiadomość i wywołuje delegata. Po przetworzeniu, Invoke przestaje blokować, a wątek wywołujący wznawia działanie Twojego kodu.

5

Należy pamiętać, że Control.InvokeRequired zwraca wartość false, jeśli użytkownik znajduje się w wątku tła ORAZ Control.IsHandleCreated ma wartość false. Chciałbym zabezpieczyć kod za pomocą Debug.Assert, który sprawdza niezarządzanego tworzenia uchwytów.

14

Osobiście lubię tę metodę:

private void ExecuteSecure(Action a) 
{ 
    if (InvokeRequired) 
     BeginInvoke(a); 
    else 
     a(); 
} 

a następnie można napisać jednej wkładki tak:

ExecuteSecure(() => this.Enabled = true); 
+0

Coś tu nie wygląda, InvokeRequired działa na Control, po prostu umieszczasz go bez niczego. Co to znaczy? – Craig

+0

InvokeRequired jest taki sam jak this.InvokeRequired. –

Powiązane problemy