J'ai lu des opinions contradictoires sur le fait de savoir si chaque élément BeginInvoke () doit être associé à un élément EndInvoke (). Existe-t-il des fuites ou d'autres problèmes associés à NE PAS appeler EndInvoke ()?
Réponses
Trop de publicités?Délégué.EndInvoke est documenté comme tu appelleras ce (c'est à dire nécessaire - d'autre fuites se produisent) - à partir de msdn:
Remarque Importante
Peu importe la technique que vous utilisez, toujours appeler EndInvoke pour compléter votre appel asynchrone.
De contrôle.EndInvoke est OK pour l'ignorer pour le feu et oublier méthodes de msdn:
Vous pouvez appeler EndInvoke pour récupérer le valeur de retour de la délégation, lorsqu' nécessaire, mais ce n'est pas nécessaire.
Toutefois, si vous utilisez Delegate.BeginInvoke
et ne veulent pas le résultat, envisager l'utilisation d' ThreadPool.QueueUserWorkItem
au lieu de cela, il va rendre la vie beaucoup plus facile, et d'éviter la douleur de l' IAsyncResult
etc.
EndInvoke n'est pas facultatif.
Plus d'infos ici
Et EndInvoke appel n'est pas une option call, c'est une partie du contrat. Si vous appelez BeginInvoke vous devez appeler EndInvoke.
L'exemple classique de pourquoi cela est nécessaire. Il est très possible que le IAsyncResult retourné à partir de BeginInvoke a alloué des ressources attaché à elle. Le plus souvent un WaitHandle de toutes sortes. Parce que IAsyncResult ne pas mettre en œuvre IDisposable un autre endroit doit être choisi pour libérer les ressources. Le seul endroit pour le faire est EndInvoke.
J'ai brièvement discuter de ce problème dans le blog suivant.
http://blogs.msdn.com/jaredpar/archive/2008/01/07/isynchronizeinvoke-now.aspx
EndInvoke n’est pas facultatif car c’est le lieu où des exceptions sont générées en cas de problème lors du traitement asynchrone.
Quoi qu'il en soit, il ne devrait y avoir aucune fuite, car si IAsyncResult contient une ressource native, il doit correctement implémenter IDisposable et disposer de telles ressources lorsque le GC appelle son finaliseur.
Ce n'est pas facultatif car l'appel de BeginInvoke utilise un WaitHandle qui utilise à son tour un objet du noyau qui gère le nombre de références qu'il contient. L'appel de EndInvoke supprime le descripteur décrivant ce compteur sur l'objet du noyau et lorsque ce nombre atteint zéro, le gestionnaire d'objets du noyau le détruit.