Comment voir facilement le nombre d'abonnements aux événements lors du débogage ?
-
20-12-2019 - |
Question
Pendant le débogage, puis-je examiner textBox1.TextChanged
voir le nombre d'abonnements aux événements ?Si oui, comment puis-je y accéder ?J'ai besoin de savoir combien d'abonnements il y a à un moment donné pour le débogage, car il semble qu'un événement soit déclenché plusieurs fois, mais je soupçonne que ce bug est vraiment dû au fait que textBox1.TextChanged += handler
est mal géré dans l'application, il y a donc trop d'abonnés.
Voici une version simplifiée de ce qui, à mon avis, se passe.Si possible, je souhaite simplement définir un point d'arrêt et compter le nombre d'abonnements à "textBox1.TextChanged":
private void textBox1_TextChanged(object sender, EventArgs e)
{
textBox1.TextChanged += textBox1_TextChanged;
MessageBox.Show("asdf");
textBox1.TextChanged -= textBox1_TextChanged;
textBox1.Text = DateTime.Now.ToString();
textBox1.TextChanged += textBox1_TextChanged;
}
Est-ce possible ou est-ce plus compliqué ?
La solution
Vous devrez utiliser Reflection pour accéder à la liste d'invocation du délégué à l'événement :
textBox1.TextChanged += textBox1_TextChanged;
MessageBox.Show("asdf");
textBox1.TextChanged -= textBox1_TextChanged;
textBox1.Text = DateTime.Now.ToString();
textBox1.TextChanged += textBox1_TextChanged;
var eventField = textBox1.GetType().GetField("TextChanged", BindingFlags.GetField
| BindingFlags.NonPublic
| BindingFlags.Instance);
var subscriberCount = ((EventHandler)eventField.GetValue(textBox1))
.GetInvocationList().Length;
Autres conseils
Si vous souhaitez uniquement le faire sous le débogueur, plutôt que par programme, alors c'est peut-être une méthode plus simple et non invasive :
class _24003458
{
event EventHandler MyEvent;
public void Test()
{
MyEvent += Handler1;
MyEvent += Handler2;
MyEvent(this, EventArgs.Empty);
}
void Handler1(object sender, EventArgs e)
{
throw new NotImplementedException();
}
void Handler2(object sender, EventArgs e)
{
throw new NotImplementedException();
}
}
Placez un point d'arrêt sur l'un des gestionnaires d'événements et, lorsqu'il se brise, consultez l'onglet Locals.L'événement, une fois développé, affichera le nombre d'appels et les gestionnaires d'événements :
Ce n'est pas possible avec un événement comme celui-ci (pour cause), cependant, c'est possible par réflexion comme Selman22 dit, au-dessus de) si vous utilisez directement un événement, vous pouvez le faire :
private event EventHandler handler;
var delegates = handler.GetInvocationList();
Vous pouvez créer une méthode membre que vous ajoutez à l'objet qui implémente le INotifyPropertyChanged
interface.Cela rend le débogage très simple :
#if DEBUG
public System.Delegate[] GetInvocationList()
{
return PropertyChanged?.GetInvocationList();
}
#endif