如何在调试时轻松查看事件订阅的数量?

时间:2014-06-02 21:17:39

标签: c# events subscription eventtrigger

在调试时,我可以查看textBox1.TextChanged以查看事件订阅的数量吗?如果是,那我该如何钻研呢?我需要知道在给定时间有多少订阅用于调试,因为它看起来像是多次触发事件,但我怀疑这个错误是因为textBox1.TextChanged += handler在应用程序中管理不当,所以也有许多订阅者。

这是我认为正在发生的事情的简化版本。如果可能的话,我只想设置一个断点并计算" 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;
}

这可能还是更复杂?

4 个答案:

答案 0 :(得分:3)

您必须使用Reflection来访问事件委托的调用列表:

    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;

答案 1 :(得分:3)

如果您只关心在调试器下进行,而不是以编程方式进行,那么这可能是一种更简单,非侵入性的方式:

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

在任一事件处理程序上放置一个断点,当它中断时,请查看Locals选项卡。展开时,该事件将显示调用计数和事件处理程序:

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

答案 2 :(得分:2)

对于这样的事件是不可能的(有充分的理由),但是,可以通过反映来实现Selman22 说,above)如果你正在使用直接你可以这样做一个事件:

private event EventHandler handler;

var delegates = handler.GetInvocationList();

答案 3 :(得分:0)

您可以创建一个成员方法,将其添加到实现INotifyPropertyChanged接口的对象中。它使调试变得非常简单:

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