Question

Remarque : Une partie d'une série: C # : Accès à des membres de formulaire à partir d'une autre de classe et msdn , mais je ne peux pas sembler acquérir la méthode qu'ils ont utilisé là-bas.

Ceci est mon remake, ce qui ne fonctionne pas.

    private void SetTextMemo(string txt)
    {
        if(this.Memo.InvokeRequired)
        {
            this.Invoke(SetTextMemo,txt); //error here
        }
        else
        {
            this.Memo.Text += txt + "\n";
        }
    }
erreurs

:

Argument '1': ne peut pas convertir les 'groupe de procédé' à 'System.Delegate'

Argument '2': ne peut pas convertir de 'string' à 'objet []

En fait, je suis en train d'accéder au mémo (ou plus probablement dit, ajouter du texte à la note) d'un autre fil à l'aide Invoke.I jamais utilisé auparavant, peut-être pourquoi je comprends mal mon erreur.

Était-ce utile?

La solution

Le plus simple est:

this.Invoke((MethodInvoker)delegate {
    this.Memo.Text += txt + "\n";
});

qui utilise une méthode anonyme pour faire la ligne de travail. Puisque vous attendre être sur un autre thread, vous pouvez tout aussi bien appeler Invoke - il est sûr même du thread d'interface utilisateur

.

Autres conseils

Si vous utilisez C # 3.0 et le 3.5 cadre les opérations suivantes

if ( this.Memo.InvokeRequired ) {
  this.Invoke((Action)(() => SetTextMemo(txt)));
} 

Votre mise en œuvre suppose que la méthode ne sera pas infiniment récursion parce que le comportement de la propriété InvokeRequired va l'empêcher. Cette hypothèse peut proove être vrai, mais il n'y a pas de problème de codage de la fonction pour éviter cette possibilité tout à fait. Voici ce que je propose:

    private void SetMemo(string txt)
    {
        Memo.Text = txt;
    }

    private delegate void MemoSetter(string txt);

    public void ThreadSafeSet(string txt)
    {
        Invoke(new MemoSetter(SetMemo), txt);
    }

Je l'habitude de gérer toute cette croix-fil, mais récemment, je suis allé avec AOP, où vous décorez simplement une méthode pour exécuter sur le thread d'interface utilisateur. Voici un exemple (de PostSharp):

public class FormsThreadAttribute : OnMethodInvocationAspect
{
  public override void OnInvocation(MethodInvocationEventArgs eventArgs)
  {
    Form f = (Form)eventArgs.Delegate.Target;
    if (f.InvokeRequired)
      f.Invoke(eventArgs.Delegate, eventArgs.GetArgumentArray());
    else
      eventArgs.Proceed();
  }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top