Vous n'avez pas besoin de conserver votre propre référence à un délégué lorsque vous effectuez un travail normal délégué BeginInvoke
; vous pouvez convertir le IAsyncResult
en AsyncResult
et récupérer le délégué de la propriété AsyncDelegate
. Et avant que quelqu'un ne dise "c'est un bidouille", it's documented as being valid at MSDN.
La classe AsyncResult est utilisée conjointement avec les appels de méthode asynchrones effectués à l'aide de délégués. Le IAsyncResult renvoyé à partir de la méthode BeginInvoke du délégué peut être converti en un AsyncResult. AsyncResult possède la propriété AsyncDelegate qui contient l'objet délégué sur lequel l'appel asynchrone a été appelé.
Vous pouvez écrire:
new GenericDelegate(DoSomething).BeginInvoke(DoSomethingComplete);
void DoSomethingComplete(IAsyncResult ar)
{
((GenericDelegate)((AsyncResult)ar).AsyncDelegate)).EndInvoke();
}
Notez que vous n'avez toujours de connaître le de type du délégué d'origine (ou du moins, je ne l'ai pas trouvé un moyen de contourner cette limitation; alors encore je n'ai pas essayé).
Par "normal" ici, je veux dire un BeginInvoke
sur une instance de délégué, en utilisant la méthode généré par le compilateur. Cette technique de moulage à AsyncResult
n'est pas garantie de fonctionner lors de l'utilisation de méthodes prédéfinies, c'est-à-dire lors de l'utilisation d'une classe qui déclare ses propres méthodes BeginX/EndX
. C'est parce que la classe peut faire quelque chose de plus intelligent en interne comme bloquer sur les ports d'achèvement d'E/S, et peut donc utiliser un type différent de IAsyncResult
. Cependant, dans le scénario tel que posé, cela fonctionnera très bien.
Plus simple pour capturer "d": d.BeginInvoke (r => {d.EndInvoke (r); ...}, null); [selon l'article de blog lié ci-dessus]. –