2017-06-09 1 views
0

Il se trouve que j'obtiens cette erreur croisée lorsque j'essaie d'appeler une zone de texte à partir d'un autre thread que le thread principal MMI. Je comprends déjà pourquoi cela arrive. J'aimerais avoir votre avis sur la façon dont je résous cela. Je l'utilise parce que je déteste ajouter des déclarations de délégués partout dans le code.Opération croisée

private void SetText(string text) 
{   
    if (textBox1.InvokeRequired) 
    { 
     this.Invoke(new Action<string>(SetText), new object[]{ text }); 
    } 
    else 
    { 
     this.textBox1.Text = text; 
    } 
} 

est-ce la bonne façon de faire? y a-t-il un moyen meilleur et plus court?

Répondre

0

Rien à redire sur ce que vous avez. Si vous ne voulez pas faire un appel récursif, vous pouvez simplement jeter un délégué anonyme dans le Invoke() appel:

private void SetText(string text) 
{ 
    if (this.InvokeRequired) 
    { 
     this.Invoke((MethodInvoker)delegate 
     { 
      this.textBox1.Text = text; 
     }); 
    } 
    else 
    { 
     this.textBox1.Text = text; 
    } 
} 
0

C'est la seule façon de le faire, bien que je voudrais faire deux changements:

1) Utilisez MethodInvoker afin de pouvoir omettre la distribution Func ou Action, mais continuez et utilisez la récursivité pour ne pas dupliquer le code.

2) Ajouter un retour au bloc d'appel, de sorte que vous n'ayez pas le bloc else. Je préfère ajouter une ligne supplémentaire que d'avoir une indentation supplémentaire.

private void SetText(string text) 
{   
    if (textBox1.InvokeRequired) 
    { 
     this.Invoke((MethodInvoker) delegate { SetText(text); }); 
     return; 
    } 

    this.textBox1.Text = text; 
} 

À la réflexion, vous pourriez avoir une méthode utilitaire qui prend une action pour faire le contrôle, et la logique réelle serait toujours à l'intérieur du lambda.

private static void InvokeIfRequired(bool required, Action action) { 
    // NOTE if there is an interface which contains InvokeRequired 
    //  then use that instead of passing the bool directly. 
    //  I just don't remember off the top of my head 
    if (required) { 
     this.Invoke((MethodInvoker) delegate { action(); }); 
     return; 
    } 

    action(); 
} 

private void SetText(string text) 
{ 
    InvokeIfRequired(textBox1.InvokeRequired,() => { 
     this.textBox1.Text = text; 
    }); 
}