【问题标题】:How to easilly see number of event subscriptions while debugging?调试时如何轻松查看事件订阅数?
【发布时间】:2014-06-02 21:17:38
【问题描述】:

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

这可能还是更复杂?

【问题讨论】:

  • 为什么要投反对票?这是个好问题。

标签: c# events subscription eventtrigger


【解决方案1】:

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

    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;

【讨论】:

    【解决方案2】:

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

    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 选项卡。该事件在展开时将显示调用计数和事件处理程序:

    【讨论】:

    • 很棒的反应。我可以做一些类似的事情来查找 ComboBox 的 TextChanged 事件(即,通过 Locals)吗?我环顾了一会儿,但在钻取时找不到 ComboBox 的事件。尽管如此,这将是有帮助的,所以谢谢。
    • 如果您可以从 this 导航到您的 ComboBox,您就可以从那里访问它的事件。
    • 在 VS 2017 中,该事件字段隐藏在调试器中。看起来 VS 调试器更改了 Locals 选项卡中的事件可见性引擎
    【解决方案3】:

    这样的事件是不可能的(有充分的理由),但是,如果您直接使用事件,则可以通过反射作为Selman22 says,above)可以这样做:

    private event EventHandler handler;
    
    var delegates = handler.GetInvocationList();
    

    【讨论】:

      【解决方案4】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-05
        • 1970-01-01
        • 1970-01-01
        • 2017-03-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多