7

While debugging, can I look into textBox1.TextChanged to see the number of event subscriptions? If yes, then how do I drill to it? I need to know how many subscriptions there are at a given time for debugging because it looks like an event is triggered multiple times, but I suspect this bug is really because textBox1.TextChanged += handler is being mismanaged in the application, so there are too many subscribers.

Here is a simplified version of what I think is happening. If possible, I just want to set a breakpoint and count up the number of subscriptions to "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;
}

Is that possible or is it more complicated?

Madmartigan
  • 143
  • 1
  • 7

4 Answers4

6

If you're only concerned with doing it under the debugger, rather than programmatically, then this is perhaps a simpler, non-invasive way:

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

Put a breakpoint on either of the event handlers, and when it breaks, look at the Locals tab. The event, when expanded, will show the invocation count and event handlers:

Screenshot of program stopped at breakpoint and Locals window showing the expanded event with invocation count and handlers

ClickRick
  • 1,553
  • 2
  • 17
  • 37
  • Awesome response. Could I do something similar to find a ComboBox's TextChanged event (i.e., via Locals)? I looked around for a while but couldn't find the ComboBox's events when drilling. This will be helpful nonetheless, so thanks. – Madmartigan Jun 03 '14 at 19:32
  • If you can navigate from `this` to your ComboBox, you'll be able to get from there to its events. – ClickRick Jun 03 '14 at 19:37
  • In VS 2017, this event field is hidden in debugger. Looks like VS debugger changed the event visibility engine in Locals tab – andreyk2 Hohlov Jun 18 '20 at 17:32
  • When I put `this.FormClosing` into the watch window, I get error CS0079: The event 'Form.FormClosing' can only appear on the left hand side of += or -= – Thomas Weller Mar 03 '23 at 12:37
  • @ThomasWeller Indeed, which is why I started from `this` and drilled down. – ClickRick Mar 05 '23 at 16:16
5

You will have to use Reflection to get to the invocation list of the event delegate:

    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;
Volma
  • 1,305
  • 9
  • 17
2

It is not possible with an event like this (for good reason), however, it is possable via reflection as Selman22 says, above) if you are using an event directly you can do so:

private event EventHandler handler;

var delegates = handler.GetInvocationList();
Community
  • 1
  • 1
BanksySan
  • 27,362
  • 33
  • 117
  • 216
1

You can create a member method which you add to the object which implements the INotifyPropertyChanged interface. It makes debugging very easy:

#if DEBUG
    public System.Delegate[] GetInvocationList()
    {
        return PropertyChanged?.GetInvocationList();
    }
#endif
Jack Miller
  • 6,843
  • 3
  • 48
  • 66