2010-11-03 10 views
1

J'ai un BackgroundWorker qui appelle une fonction sur un thread non-GUI. J'ai remarqué que pour certains éléments de formulaire, je peux sortir avec la mise à jour de l'interface graphique sans faire l'appel. D'autres entraîneront toujours une erreur d'exécution car le programme a tenté de mettre à jour l'interface graphique d'une manière non threadsafe.Comment se fait-il que je n'aie pas besoin d'une invocation pour certains éléments de formulaire d'un thread non-GUI?

Pourquoi est-ce?

Répondre

5

Vous êtes probablement tombé sur des méthodes ou des propriétés qui ne vérifient pas le contexte et ne lancent pas d'exception. Cela ne veut pas dire que c'est une bonne idée de le faire. En fait, je l'éviterais à tout prix.

Mise à jour: En supposant WinForms ici. Si vous pensez qu'il est trop lourd pour invoquer, utiliser une méthode d'extension:

public static class ControlExtensions 
{ 
    public static void Do(this Control c, Action f) 
    { 
     if (c.InvokeRequired) 
     { 
     c.Invoke(f); 
     } 
     else 
     { 
     f(); 
     } 
    } 
} 

Puis, en DoWork de BackgroundWorker:

// Background work here 
this.Do(() => 
{ 
    // This runs on UI thread 
}); 

Je trouve cela beaucoup plus facile à utiliser que BackgroundWorkers ReportProgress.

+0

Est-il coûteux d'appeler cette fonction pour les contrôles qui ne nécessitent pas d'invocation? – Pieter

+0

Comme vous pouvez le voir dans le code ci-dessus, non, ce n'est pas cher. Si Invoke n'est pas requis, l'appel sera effectué dans le même thread. Je ne m'inquiéterais pas pour ça. Si vous traitez des dizaines de milliers d'éléments, ne signalez pas de progression pour chaque élément, ou le redessin sera lent. :) –

2

Tous les éléments gui et leurs méthodes ne sont pas traduits en WM_something. Il existe des méthodes qui fonctionnent directement sans utiliser la file d'attente de messages. Par conséquent, ils sont sûrs à utiliser à partir de n'importe quel thread.

+0

Bon point, mais il est si facile d'invoquer, que je pense toujours qu'il est plus sûr de ne pas faire de telles hypothèses. –

+0

Je suis d'accord - ainsi, pour être du bon côté, Invoke * toujours *! –