čtvrtek 2. června 2011

Volání metody z GUI vlákna nebo worker vlákna

Pokud programujete aplikaci s GUI, která provádí nějaké dlouhé výpočty, pravděpodobně dřív nebo později použijete pracující vlákno na dlouhý výpočet, zatímco hlavní vlákno bude schopno stále reagovat na uživatelovu interakci.


V tu chvíli nastává problém, kdy nemůžete pracovat s prvky GUI (textboxy, tlačítka apod.) z pracujícího vlákna, pokud byly tyto prvky vytvořeny hlavním vláknem. Toto omezení se vyřeší notifikací z pracujícího vlákna, že chceme následující kód vykonat na hlavním vlákně.

public TextBox tb;
// Metoda volaná buď z pracujícího vlákna, nebo z hlavního vlákna
public void MyMethod(object argument)
{
     MethodInvoker method = delegate
    {
       // Pokud je metoda volana z pracujiciho vlakna a tb byl vytvoren v hlavnim vlakne,
       // na tomto miste bysme dostali InvalidOperationException, pokud bysme kod
       // volali primo.
       tb.Text = argument.ToString();
    };
     if(tb.InvokeRequired == true)
    {   
         // Vynuceni volani metody z hlavniho vlakna 
         this.BeginInvoke(method);
    }
    else 
   {
      method.Invoke();
   }
}

Zpráva InvalidOperationException, pokud se budeme snažit přistupovat k prvku z pracujícího vlákna, který byl vytvořen v hlavním vlákně: 
"Cross-thread operation not valid: Control 'tb' accessed from a thread other than the thread it was created on."


MethodInvoker reprezentuje bezparametrického delegáta bez návratového typu (resp. návratový typ void). 

Žádné komentáře:

Okomentovat