2009-08-13 3 views
25

This page in the MS documentation, couvrant asynchronisme dans les applications Windows Forms, déclare:Est-ce que chaque BeginInvoke doit être suivi d'un EndInvoke?

Vous pouvez appeler EndInvoke pour récupérer la valeur de retour du délégué, si neccesary, mais ce n'est pas nécessaire. (italique ajouté)

This page covering the general case of asynchronous delegates, déclare quelque chose de différent:

Quelle que soit la technique que vous utilisez, appelez toujours EndInvoke pour terminer votre appel asynchrone.

Ces deux semblent être en conflit direct.

Qu'est-ce qui est vrai? Quelqu'un peut-il expliquer?

voir aussi, a post by Phil Haack.

connexes: Is EndInvoke optional, sort-of optional, definitely not optional?

Répondre

22

Sauf si la documentation d'une interface indique explicitement le contraire, vous devez appeler EndInvoke pour chaque endroit que vous appelez BeginInvoke. La raison principale est que EndInvoke est le seul moment où le propriétaire peut libérer certaines ressources qui peuvent être allouées pour l'appel BeginInvoke (comme un WaitHandle).

Mais il existe des exceptions à cette règle. Les API telles que Control.BeginInvoke ne nécessitent pas d'EndInvoke, mais elles sont explicites dans la documentation.

13

sont vraies - ils sont différents appels.

En général vous devez toujours appeler EndInvoke pour vous assurer que toutes les ressources acquises par l'appel asynchrone sont libérées. Toutefois, l'équipe Windows Forms a garanti que vous n'avez pas besoin de faire cela pour Control.Invoke. Vous devrez peut-être le faire pour d'autres implémentations de ISynchronizeInvoke cependant.

+0

Je suis d'accord avec la plupart de votre réponse, sauf le commentaire qu'ils sont "différents appels". Ils ne semblent pas être des appels différents du tout. Ne parlent-ils pas tous les deux de EndInvoke sur des délégués asynchrones? C'est juste que les EndInvoke sur les délégués de contrôle sont un cas particulier. – Cheeso

+3

@Cheeso: Non - Control.BeginInvoke n'est pas un appel * sur * un délégué du tout. Il * prend * un délégué. –

1

J'ai utilisé la méthode fire-and-forget avec les délégués avant que les résultats soient "utiles si disponibles, mais pas obligatoires". N'oubliez pas que vous n'avez aucune garantie d'achèvement avec cette méthode. En particulier, voici un endroit que je l'utilise:

  • Démarrer un délégué pour vérifier les mises à jour de l'application
  • délégué commence une requête Web avec un délai d'attente
  • Si une erreur/délai d'attente se produit, ou si l'application est mise à jour, la méthode retourne simplement
  • Si l'application est obsolète, je place un non-focus-vol un message systray indiquant si (aucune icône systray à moins que la mise à jour est disponible)

De toute façon, L'application continue ininterrompue.

Questions connexes