在调试时,我可以查看一下 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;
}

这可能吗还是更复杂?

有帮助吗?

解决方案

您必须使用反射来获取事件委托的调用列表:

    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;

其他提示

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

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

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

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

然而,这样的事件是不可能的(有充分的理由), 可以通过反射作为 塞尔曼22 说, 多于)如果您直接使用事件,您可以这样做:

private event EventHandler handler;

var delegates = handler.GetInvocationList();

您可以创建一个成员方法,将其添加到实现该对象的对象中 INotifyPropertyChanged 界面。它使调试变得非常容易:

#if DEBUG
    public System.Delegate[] GetInvocationList()
    {
        return PropertyChanged?.GetInvocationList();
    }
#endif
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top