Domanda

Durante il debug, posso guardare in textBox1.TextChanged per vedere il numero di abbonamenti degli eventi?Se sì, allora come faccio perforare ad esso?Devo sapere quanti abbonamenti ci sono in un dato momento per il debug perché sembra che un evento venga attivato più volte, ma sospetto che questo bug sia davvero perché textBox1.TextChanged += handler è gestito nell'applicazione, quindi ci sono troppi abbonati. .

Ecco una versione semplificata di ciò che penso stia succedendo.Se possibile, voglio solo impostare un punto di interruzione e contare il numero di abbonamenti su "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;
}
.

è possibile o è più complicato?

È stato utile?

Soluzione

Dovrai usare la riflessione per raggiungere l'elenco di invocazione del delegato dell'evento:

    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;
.

Altri suggerimenti

Se sei preoccupato solo di farlo sotto il debugger, piuttosto che a livello di programmazione, allora questo è forse un modo più semplice, non invasivo:

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();
    }
}
.

Metti un punto di interruzione su uno dei gestori degli eventi, e quando si rompe, guarda la scheda del posto.L'evento, quando espanso, mostrerà il conteggio dell'invocazione e i gestori di eventi:

Screenshot del programma interrotto alla finestra di breakpoint e locali che mostra l'evento espanso con il conteggio e gli handler di invocazione

Non è possibile con un evento come questo (per buona ragione), tuttavia, è probabile tramite la riflessione come Selman22 dice, sopra ) Se si utilizza un evento direttamente puoi farlo:

.
private event EventHandler handler;

var delegates = handler.GetInvocationList();
.

È possibile creare un metodo membro che si aggiunge all'oggetto che implementa l'interfaccia INotifyPropertyChanged.Rende il debug molto facile:

#if DEBUG
    public System.Delegate[] GetInvocationList()
    {
        return PropertyChanged?.GetInvocationList();
    }
#endif
.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top