Как легко увидеть количество подписок на события во время отладки?

StackOverflow https://stackoverflow.com//questions/24003458

Вопрос

Могу ли я во время отладки изучить 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;
}

Возможно ли это или все сложнее?

Это было полезно?

Решение

Вам придется использовать 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;

Другие советы

Если вы хотите сделать это только в отладчике, а не программно, то это, возможно, более простой и неинвазивный способ:

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