2011-07-13 6 views
2

Pourquoi la sécurité de mise à jour de l'interface utilisateur cross-thread n'est-elle pas gérée automatiquement?Pourquoi le compilateur (ou le runtime) ne fait-il pas le modèle InvokeRequired pour moi?

Pour garantir la sécurité des threads lors de la mise à jour éventuelle de l'interface utilisateur d'un autre thread, nous devons écrire le modèle if (Control.InvokeRequired()) Invoke(..), ou quelque chose d'équivalent. Est-ce que le runtime peut observer quand j'appelle une méthode de mise à jour d'interface d'un autre fil et marshal l'appel pour moi? Il doit savoir quand cela est nécessaire car il lance une exception si vous essayez de le faire sans les précautions nécessaires.

Le compilateur peut-il simplement appliquer le modèle pour moi à chaque appel de mise à jour de l'interface utilisateur? Si cela entraînait un surcoût inacceptable, cette fonctionnalité pourrait peut-être être contrôlée par un attribut d'application (le développeur pourrait appliquer l'attribut uniquement lors de l'écriture d'une application multithread dans laquelle des mises à jour de l'interface utilisateur croisée vont se produire).

Je peux imaginer plusieurs réponses potentielles: soit c'est une idée stupide parce que, soit c'est impossible/irréalisable parce que, ou on ne voit pas juste ajouter assez de valeur pour justifier le coût du développement.

+1

Parce qu'il s'agit d'un anti-modèle largement abusé. Il est très rare d'écrire du code pouvant s'exécuter sur * deux * le thread de l'interface utilisateur et un thread de travail. InvokeRequired doit être utilisé pour les diagnostics. Parce que si elle renvoie false lorsque vous * savez * que le code est en cours d'exécution sur un agent, alors il y a quelque chose qui ne va pas. –

+0

@Hans: cela peut-il arriver? –

+0

Oui, démarrer le thread trop tôt, avant que Windows ne crée la fenêtre. Ou plus généralement, en oubliant de s'assurer que le fil s'est arrêté avant de permettre la fermeture de la fenêtre. –

Répondre

1

Je ne peux pas répondre à pourquoi même si je pouvais demander si cette fonction vaut le coût des tests, documentation de maintenance etc .... lorsque vous pouvez ajouter une méthode telle que:

public static void UpdateControl(this Control ctrl, Action<Control> action) 
    { 
     if (ctrl.InvokeRequired) 
     { 
      ctrl.Invoke(action,ctrl); 


     } 
     else 
     { 
      action(ctrl); 

     } 

    } 

Vous pouvez ensuite utilisez ceci comme this.textBox.UpdateControl(c=>c.Text="Thread Safe");

+0

D'accord. Il y a bien sûr de nombreuses caractéristiques linguistiques qui sont considérées, mais jugées non valables à mettre en œuvre. Et si c'est le cas ici, j'aimerais bien le confirmer (j'espère que Eric Lippert ou un autre architecte de MS s'en mêlera). –

Questions connexes