Quelle est la différence entre QueueUserWorkItem () et BeginInvoke (), pour effectuer une activité asynchrone sans aucun type de retour nécessaire
À la suite de mon BeginInvoke()/EndInvoke() de la question, il y a de grandes différences dans la performance/quelque chose d'autre entre Délégué.BeginInvoke() et à l'aide de QueueUserWorkItem() pour appeler un délégué de manière asynchrone?
source d'informationauteur endian
Vous devez vous connecter pour publier un commentaire.
http://blogs.msdn.com/cbrumme/archive/2003/07/14/51495.aspx
dit:
La principale chose que je peux penser avec
QueueUserWorkItem
est que vous devez utiliser leWaitCallback
type délégué, qui semble difficile si vous avez déjà unSomeRandomDelegate
exemple et certains arguments. La bonne nouvelle est que vous pouvez résoudre ce problème avec une fermeture:Ce modèle assure aussi vous obtenir bon typage fort au moment de la compilation (à la différence du passage d'un
object
état arg àQueueUserWorkItem
et le jetant dans la cible de la méthode). Ce modèle peut aussi être utilisé lors de l'appel de méthodes directement:Évidemment, sans une
EndInvoke
équivalent, vous ne pouvez pas obtenir une valeur de retour, à moins que vous appelez une méthode /déclencher un événement /etc à la fin de votre méthode... sur une même note, vous devez être prudent avec la gestion des exceptions.La EndInvoke() est utile mais rarement mentionné comportement - il renvoie toutes les exceptions non gérées que le délégué générés dans le contexte du thread d'origine de sorte que vous pouvez déplacer à l'exception du traitement de la logique dans le code principal.
Aussi, si votre délégué a/réf paramètres, ils seront ajoutés à la EndInvoke() signature vous permettant de les obtenir lors de la fin de l'exécution de la méthode.
Si vous appelez de pool de threads.QueueUserWorkItem, les exceptions soulevées dans l'élément de travail sera gérée sur le thread d'arrière-plan (sauf si vous avez explicitement les attraper). Dans .Net 2 et au-dessus de cette volonté de mettre fin à votre domaine d'application.
Si vous appelez délégué.BeginInvoke (), puis les exceptions sont en attente pour être relancée lorsque EndInvoke() est appelée. Si vous n'appelez jamais EndInvoke(), puis les exceptions sont essentiellement des fuites de mémoire (comme n'importe quel autre état qui n'est pas libéré par l'opération asynchrone).
Il ne devrait pas être une grosse différence, je pense aussi que le BeginInvoke/EndInvoke pour un délégué utilise le pool de threads de s'exécuter.
Il ne devrait pas y avoir de différence de performances, à la fois comme Délégué.BeginInvoke et de pool de threads.QueueUserWorkItem s'exécuter sur un thread du pool.
La plus grande différence est que si vous appelez BeginInvoke, vous êtes obligé à appeler EndInvoke à un certain point. En revanche, le pool de threads.QueueUserWorkItem est "fire and forget". Qui a des avantages et des inconvénients. L'avantage étant que vous pouvez l'oublier. L'inconvénient étant que vous n'avez aucun moyen de le savoir, sauf si vous ajoutez votre propre synchronisation/mécanisme de notification, lorsque la tâche est terminée.