Vous n'êtes pas obligé d'appeler EndInvoke
; ne pas l'appeler signifie simplement:
- Vous n'obtenez pas la valeur de retour de la méthode.
- Toutes les exceptions levées pendant l'exécution de la méthode disparaîtront simplement.
On dirait que vous voulez « feu et oublier », de sorte que le moyen le plus simple est d'utiliser un délégué anonyme, par exemple:
var del = new Action(foo.Bar);
del.BeginInvoke(iar =>
{
try
{
del.EndInvoke(iar);
}
catch (Exception ex)
{
// Log the message?
}
}, null);
C'est ce qui se passe lorsque vous exécutez ce code:
- Un nouveau thread est alloué (simplement) pour le délégué. Le thread reçoit le délégué
del
et le délégué anonyme (iar => ...
).
- Le thread exécute
del
.
- Lorsque l'exécution est terminée (ou qu'une exception se produit), le résultat ou l'exception est stocké et le délégué anonyme est exécuté.
- À l'intérieur du délégué anonyme, lorsque le
EndInvoke
est appelé, le résultat de la méthode est renvoyé ou l'exception est levée (le cas échéant).
Notez que l'exemple ci-dessus est très différent de:
// This is pointless and is still, essentially, synchronous.
del.EndInvoke(del.BeginInvoke(null, null));
Edit: Vous devriez toujours appeler End*
. Je ne l'ai jamais trouvé un scénario où ne pas l'appeler pose un problème, mais c'est un détail de mise en œuvre et est relying on undocumented behavior.
Enfin, votre solution échouerait le processus si une exception est levée,
vous pouvez tout simplement passer null comme délégué si vous ne vous souciez pas de l'exception (
del.BeginInvoke(myStruct, null, null);
).
Donc, comme un dernier exemple ce que vous cherchez est probablement:
public class A
{
// ...
void Foo(S myStruct){...}
void FooAsync(S myStruct)
{
var del = new Action<S>(Foo);
del.BeginInvoke(myStruct, SuppressException, del);
}
static void SuppressException(IAsyncResult ar)
{
try
{
((Action<S>)ar.AsyncState).EndInvoke(ar);
}
catch
{
// TODO: Log
}
}
}
Il est vrai que vous n'êtes pas « nécessaire » pour appeler 'EndInvoke', mais si vous ne Tu vas avoir des fuites de mémoire. http://stackoverflow.com/questions/1712741/why-does-asynchronous-delegate-method-require-calling-endinvoke?rq=1 –
@MattKlein non non. https://gist.github.com/jcdickinson/9109599. La réponse de SLaks est quelque peu correcte cependant, dans certains scénarios, un suivi est effectué avec des paires Begin/End-Invoke. Un exemple est: si vous n'appelez pas EndInvoke sur les opérations Socket, vos compteurs de performance de socket vont complètement détraqué (pas de fuite de mémoire, les valeurs seront juste follement incorrectes). –
Peut-être que ce serait un commentaire utile à ajouter à la réponse de SLaks. –