Appeler d'un Gestionnaire d'événements
J'ai le Gestionnaire suivant:
private EventHandler<MyEventArgs> _myEventHandler;
public event EventHandler<MyEventArgs> MyEvent
{
add { _myEventHandler += value; }
remove { _myEventHandler -= value; }
}
Quelqu'un pourrait expliquer la différence entre les extraits suivants?
Extrait De EventHandler (A):
//Snippet A:
if (_myEventHandler != null)
{
_myEventHandler(new MyEventArgs());
}
Extrait De BeginInvoke (B):
//Snippet B:
if (_myEventHandler != null)
{
_myEventHandler.BeginInvoke(new MyEventArgs(), ar =>
{
var del = (EventHandler<MyEventArgs>)ar.AsyncState;
del.EndInvoke(ar);
}, _myEventHandler);
}
De précisions: Quelle est la différence entre invoquant un Gestionnaire d'événements "comme il est", et à l'aide de BeginInvoke
?
OriginalL'auteur WaltiD | 2011-08-11
Vous devez vous connecter pour publier un commentaire.
La
BeginInvoke
approche est asynchrone, ce qui signifie qu'il est soulevé sur un thread différent. Cela peut être dangereux si les gens ne s'y attendent pas, et c'est plutôt rare pour des événements, mais il peut être utile.Notez également que à proprement parler vous devriez instantané le gestionnaire d'événement de la valeur - c'est surtout vrai si (via
Begin*
vous traitez avec les threads.Également de noter que votre inscription à l'événement lui-même n'est pas thread-safe; encore une fois, ce que des questions si vous avez affaire avec le multi-threading, mais le intégré le terrain comme événement est thread-safe:
Les questions d'éviter ici sont:
pas qui en appelle à un délégué de façon asynchrone signifie qu'il se passe sur un thread de travail. Sinon, comment serait-il exécuter de manière asynchrone? Notez que ce n'est subtilement différent de Contrôle.BeginInvoke qui continuer sur le même thread si vous êtes déjà sur le thread de l'INTERFACE utilisateur
Si le délégué est de faire IO (c'est à dire, les blocs) de contrôle est renvoyé vers le site d'appel. Lorsque ce est terminé, le fil d'origine est interrompu pour finir le reste de la méthode. Ce que j'ai compris, pas de nouveaux threads sont créés, c'est toutes les interruptions à partir de là.
C'est si vous avez été en utilisant AsyncIO. À l'aide de gestionnaires d'événements pour appeler les délégués qui font IO ne change pas le comportement du Gestionnaire d'événements. BeginInvoke sur un gestionnaire d'événements va utiliser le pool de threads. Période.
c'est peut-être vrai des choses comme FileStream.BeginRead - cependant, ici nous sommes tout simplement à l'aide de Délégué.BeginInvoke - qui est d'un usage général, "exécuter une méthode" de l'API. Il sait rien à propos de ce que la cible méthode de faire, donc utilise le fil de la piscine pour appeler la méthode.
OriginalL'auteur Marc Gravell
BeginInvoke()
appeler immédiatement retourne le contrôle à l'appelant fil et exécuter un délégué dans un thread séparé de laThreadPool
, ce sera donc une sorte de mode d'exécution asynchrone.OriginalL'auteur sll