web-dev-qa-db-fra.com

Utiliser C # MethodInvoker.Invoke () pour une application graphique ... est-ce bien?

En utilisant C # 2.0 et le délégué MethodInvoker, j'ai une application graphique qui reçoit un événement du thread graphique ou d'un thread de travail.

J'utilise le modèle suivant pour gérer l'événement dans le formulaire:

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

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

En utilisant ce modèle, je ne duplique pas le code de l'interface utilisateur mais je ne suis pas sûr de savoir si cette méthode est bonne.

En particulier, la ligne

method.Invoke()

utilise-t-il un autre thread pour appeler ou traduit-il un peu en appel direct à la méthode sur le thread d'interface graphique?

26
Stécy

L'appel method.Invoke() exécute le délégué sur le thread en cours d'exécution. L'utilisation de BeginInvoke(method) garantit que le délégué est appelé sur le thread d'interface graphique.

C'est le moyen approprié d'éviter la duplication de code lorsque la même méthode peut être appelée à partir du thread d'interface graphique et d'autres threads.

21
CMerat

Personnellement j'aime cette méthode:

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

Et puis vous pouvez écrire des one-liners comme ceci:

ExecuteSecure(() => this.Enabled = true);
15
Stephan Ryer

N'oubliez pas que Control.InvokeRequired renvoie false si vous êtes sur le thread d'arrière-plan ET que Control.IsHandleCreated est false. Je voudrais sauvegarder le code avec un Debug.Assert qui vérifie la création de descripteurs non gérés.

5
GregC

Pour WinForms, appeler Control.Invoke(Delegate) envoie un message à la pompe à messages de l'interface utilisateur de thead. Le fil traite ensuite le message et appelle le délégué. Une fois qu'il a été traité, Invoke cesse de bloquer et le thread appelant reprend l'exécution de votre code.

2
Samuel

Il effectue l'appel sur le même fil. Vous pouvez vérifier en parcourant le code. Il n'y a rien de mal avec cette approche.

0
Nick Whaley