2010-09-06 2 views
3

en passant par this article, je suis tombé sur cette déclaration -Utilisation VerifyAccess et méthodes CheckAccess de DispatcherObject

Si vous écrivez vos propres objets WPF , tels que les commandes, toutes les méthodes que vous utilisez doivent appeler VerifyAccess avant qu'ils effectuent un travail. Ce garantit que vos objets ne sont utilisés sur le thread d'interface utilisateur, comme celui-ci

//Using VerifyAccess and CheckAccess 
public class MyWpfObject : DispatcherObject 
{ 
    public void DoSomething()  
    { 
     VerifyAccess(); 

     // Do some work 
    } 

    public void DoSomethingElse() 
    { 
     if (CheckAccess()) 
     { 
      // Something, only if called 
      // on the right thread 
     } 
    } 
} 

Je ne l'ai pas vu cela dans aucun des contrôles personnalisés que je suis venu à travers (pour autant que je me souviens).

  • Utilisez-vous cela lors de la création de contrôles personnalisés?
  • Est-il nécessaire de le faire ou simplement agréable d'avoir?
  • Quelqu'un at-il jamais rencontré un problème en raison de l'absence de cela dans vos contrôles?

Répondre

6

Nah, jamais utilisé ceci. Et n'a jamais remarqué que quelqu'un l'utilise dans le contexte des contrôles personnalisés. Cette règle n'est pas non plus suivie dans WPF Toolkit. Cette approche pollue non seulement le code, mais rend également votre contrôle personnalisé responsable de quelque chose dont il ne devrait pas se soucier. Considérez situation où vous faites toujours:

// Don't do this in all methods of your custom control! 
public void Foo() 
{ 
    if (!CheckAccess()) 
    { 
    Dispatcher.Invoke(()=> Foo()); // Transit to UI Thread 
    return; 
    } 
    // .. do work in UI. 
} 

À première vue, ce code semble très bien. Si vous n'êtes pas dans le thread UI, passez au thread UI, effectuez l'opération et renvoyez le résultat. Droite? - FAUX!

problème 1. Lorsque vous appelez Dispatcher.Invoke() vous bloquer thread appelant jusqu'à ce que votre demande est traitée par thread d'interface utilisateur. Cela conduit à des performances médiocres. Bien sûr, vous pouvez le changer en Dispatcher.BeginInvoke() maintenant vos clients doivent être conscients que leur opération est effectuée de manière asynchrone. C'est à dire. si le client écrit quelque chose à contrôler, puis le relit immédiatement, il n'y a aucune garantie que l'opération soit déjà exécutée par le thread de l'interface utilisateur.

Problème 2. Envisager des appels ultérieurs à la méthode Foo() à partir d'un thread non UI. Par exemple, il est appelé dans le cycle:

// Somewhere not in UI 
for (int i = 0; i < 1000000; i++) 
{ 
    control.Foo(); // Looks good, but performance is awful! 
} 

Au lieu de bloquer thread appelant 1000000 fois, développeur pourrait mettre en œuvre un contrôle dans le thread appelant et de transit à l'assurance-chômage en cas de besoin, au lieu de sauter Inconsciemment et de la valeur entre les fils.

En outre, WPF effectuera cette vérification pour vous lorsque vous accédez à l'élément d'interface utilisateur à partir d'un thread non-UI. Il crie assez fort pour écraser l'application et être entendu par le développeur qui a fait quelque chose de mal :).

Espérons que cela aide.

+0

Ouais, c'est utile. Je voulais juste savoir si je suis le seul à ne pas l'utiliser et à manquer quelque chose. Merci. – akjoshi

Questions connexes