C# Est l'action.BeginInvoke(l'action.EndInvoke,null) une bonne idée?
Si je veux faire un "fire and forget" de code, mais que vous voulez toujours vous assurer que ma mémoire est nettoyé (par Pourquoi ne asynchrone de la méthode du délégué appellent EndInvoke?), seront les suivantes atteindre cet objectif?
Action myAction = () => LongRunTime();
myAction.BeginInvoke(myAction.EndInvoke,null);
J'ai regardé mais je n'ai pas vu le modèle utilisé n'importe où. Plutôt, les gens utilisent un annonomoyus méthode que leur rappel (comme La bonne façon de mettre fin à un BeginInvoke?) ou ils définissent une réelle méthode de rappel. Puisque je n'ai pas vu quelqu'un d'autre le faire, ça me fait penser qu'il soit, n'a pas de travail ou qui est autrement une mauvaise idée.
Merci!
Je ne vois pas de problème avec l'aide d'une méthode de conversion de groupe au cours d'une expression lambda.
Si vous pouvez ajouter une réponse d'une manière ou d'une autre si cette technique ne sera pas provoquer une fuite de mémoire alors que serait la réponse que je cherche. Merci!
Si vous pouvez ajouter une réponse d'une manière ou d'une autre si cette technique ne sera pas provoquer une fuite de mémoire alors que serait la réponse que je cherche. Merci!
OriginalL'auteur Matt Klein | 2013-04-12
Vous devez vous connecter pour publier un commentaire.
À l'aide d'une méthode de conversion de groupe au lieu d'un délégué est très bien, la
EndInvoke
sera toujours appelée sur votreAction
. Il n'y a rien d'autre à faire, car c'est un feu et oublier d'appel.Malheureusement, il est un peu dur directement de prouver de manière irréfutable que EndInvoke est appelé, depuis
Action
est un délégué et nous ne pouvons pas juste ajouter un point d'arrêt sur une classe de la BCL.Ce code (périodiquement) inspecter certains domaine privé de l'IAsyncResult retourné par
BeginInvoke
, qui semble garder une trace de savoir si ou de ne pasEndInvoke
a été appelé encore:J'ai vérifié à l'aide de SOS qu'il n'y a pas tout réussi fuites de mémoire. J'ai aussi essayé plusieurs autres preuves, mais ils ont été plus de circonstance que celui-ci, je pense.
Intéressant que j'ai découvert au cours de mon enquête: le
myAction.BeginInvoke
appel apparaîtra sur les profileurs de l'utilisation des instruments, maismyAction.EndInvoke
ne le fait pas.La Tâche était d'ailleurs le point, mais voici un exemple, sans une Tâche, si vous préférez.
+1 Merci Thorarin! Beaucoup de détails et de la recherche!
OriginalL'auteur
Aujourd'hui il pourrait être fait comme
async/await
est d'environ permettant à un seul thread de continuer à travailler tout autre chose qui se passe en arrière-plan.Aussi, il n'a pas vraiment de sens pour
await UpdateData();
à la fin d'un lambda qui est en cours d'exécution dans le pool de threads. Peut-être vous manque juste//do extra work
après laawait
, mais comme c'est écrit, il peut confondre les gens qui ne comprennent pas si vous souhaitez utiliserasync
/await
.OriginalL'auteur