Удаление всех обработчиков событий сразу

используйте новая Дата () .getTime ()

getTime (), метод возвращает количество миллисекунд с полуночи от 1 января 1970.

напр.

var start = new Date().getTime();

for (i = 0; i < 50000; ++i) {
// do something
}

var end = new Date().getTime();
var time = end - start;
alert('Execution time: ' + time);

5
задан Neuron 20 October 2017 в 18:03
поделиться

3 ответа

Вы можете использовать Delegate.RemoveAll () . (Часть, которая вас интересует, находится в button2_Click )

public void Form_Load(object sender, EventArgs e) 
{ 
    button1.Click += new EventHandler(button1_Click);
    button1.Click += new EventHandler(button1_Click);
    button2.Click += new EventHandler(button2_Click);
    TestEvent += new EventHandler(Form_TestEvent);
}
event EventHandler TestEvent;
void OnTestEvent(EventArgs e)
{
    if (TestEvent != null)
        TestEvent(this, e);
}
void Form_TestEvent(object sender, EventArgs e)
{
    MessageBox.Show("TestEvent fired");
}
void button2_Click(object sender, EventArgs e)
{
    Delegate d = TestEvent as Delegate;
    TestEvent = Delegate.RemoveAll(d, d) as EventHandler;
}
void button1_Click(object sender, EventArgs e)
{
    OnTestEvent(EventArgs.Empty);
}

Обратите внимание, что он не изменяет содержимое делегатов, которые вы ему передаете, он возвращает измененный делегат. Следовательно, вы не сможете изменить события на кнопке, которую вы добавили в форму, из формы, так как button1.Клик может иметь только + = или ] - = , а не = . Это не будет компилироваться:

button1.Click = Delegate.RemoveAll(d, d) as EventHandler;

Также убедитесь, что где бы вы это ни реализовали, вы следите за потенциальными условиями гонки . Вы можете столкнуться с действительно странным поведением, если удаляете обработчики из события, которое вызывается другим потоком!

5
ответ дан 14 December 2019 в 08:57
поделиться
public class TheAnswer
{
    public event EventHandler MyEvent = delegate { };

    public void RemoveFromMyEvent(string methodName)
    {
        foreach (var handler in MyEvent.GetInvocationList())
        {
            if (handler.Method.Name == methodName)
            {
                MyEvent -= (EventHandler)handler;
            }
        }
    }
}

РЕДАКТИРОВАТЬ 2: Приношу извинения за недоразумение - я вижу, что вы довольно четко заявили о том, что не имеете доступа к источникам событий в своем исходном сообщении.

Самый простой способ, которым я могу это сделать. Чтобы решить эту проблему, необходимо реализовать общий словарь привязок объектов к документу. Когда объект входит в документ, проверьте словарь на наличие привязки к другому документу; если они есть, удалите обработчики, которые ссылаются на старый документ, прежде чем добавлять их для нового. В любом случае обновите словарь с помощью новой привязки.

Я думаю, что в большинстве случаев влияние на производительность и память будет незначительным: если вы не имеете дело с десятками тысяч мелких объектов и часто обмениваетесь ими между документами, накладные расходы на память каждой пары ключ / значение и снижение производительности для каждой операции поиска должны быть довольно небольшими.

В качестве альтернативы: если вы можете обнаружить (в обработчиках событий документа), что отправитель события больше не имеет отношения к документ, вы можете отделить там события.

Это похоже на те идеи, которые вы, возможно, уже отвергли, но, может быть, и нет!

1
ответ дан 14 December 2019 в 08:57
поделиться

Используйте Delegate.RemoveAll (возможно, используя отражение, если экземпляр Delegate является частным).

1
ответ дан 14 December 2019 в 08:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: