2011-06-07 5 views
3

J'ai une application avec deux threads. L'un d'eux (T1) est la forme principale de l'interface graphique, un autre (T2) est la fonction qui fonctionne en boucle. Lorsque T2 reçoit certaines informations, il doit appeler la fonction avec le formulaire GUI. Je ne suis pas sûr que je le fais bien.beginInvoke, GUI et thread

Fonction d'appel T2 FUNCTION, qui met à jour quelque chose sous forme d'interface graphique.

public void f() { 
     // controler.doSomething(); 
    } 


public void FUNCTION() { 

    MethodInvoker method = delegate { 
      f(); 
    }; 

    if (InvokeRequired) { 
     BeginInvoke(method); 
    } else { 
      f(); 
    } 
} 

Mais maintenant je dois déclarer deux fonctions. Comment utilise-t-il une seule fonction? Ou comment ça va?

Répondre

14

Vous pouvez le faire en une seule méthode en appelant vous invoquer:

public void Function() 
{ 
    if (this.InvokeRequired) 
    { 
     this.BeginInvoke(new Action(this.Function)); 
     return; 
    } 

    // controller.DoSomething();   
} 

Modifier en réponse aux commentaires:

Si vous avez besoin de passer des arguments supplémentaires, vous pouvez le faire par en utilisant une expression lambda comme suit:

public void Function2(int someValue) 
{ 
    if (this.InvokeRequired) 
    { 
     this.BeginInvoke(new Action(() => this.Function2(someValue))); 
     return; 
    } 

    // controller.DoSomething(someValue);   
} 
+1

modèle Nice. Un appel récursif pour vous invoquer si vous avez été appelé à partir d'un deuxième fil. Je soutiendrais que l'invocation devrait être faite de manière synchrone, donc l'appel du second thread (qui semble synchrone, juste un appel de méthode ordinaire) fonctionnerait de la même manière que s'il était appelé depuis le thread graphique, en effectuant la tâche appropriée avant de retourner. – KeithS

+0

Intéressant: Je ne l'avais pas vu faire comme ça ... ça ne provoque pas une boucle sans fin ??? – IAbstract

+0

@nirmus: Après l'accolade fermante - je pensais que l'objectif était de supprimer la deuxième fonction ["f()"] - ici, il est placé dans la fonction principale, après l'accolade. Fondamentalement, si vous avez besoin d'une invocation, vous vous invoquez, et sinon, vous pouvez simplement faire ce que vous voulez faire ... –

3

Cela me semble bon. Vous pourriez être en mesure de changer le délégué anonyme à un lambda, ce qui est un peu plus propre. Pour se débarrasser de la f() déclaration de méthode, vous pouvez inline son code dans le délégué, puis soit le délégué Invoke comme MethodInvoker ou appelez simplement comme vous le feriez pour tout autre méthode:

public void FUNCTION() { 

    MethodInvoker method =()=> controller.doSomething(); 

    if (InvokeRequired) { 
     BeginInvoke(method); 
    } else { 
      method(); 
    } 
} 
+0

C'est une bonne solution.Je dois apprendre quelque chose sur la fonction lambda, parce que je vois qu'il a une possibilité intéressante. Merci pour l'aide. – nirmus