Я столкнулся со следующей ситуацией (. C#/Net здесь, но я думаю, что это общая проблема):Отправитель событие получает удалялись в кодексе обработчика событий клиента
- Некоторые из наших типов объектов (которые являются коллекции) являются одноразовыми типами (IDisposable на C#, который позволяет клиентам явно указывать объект «вам больше не нужен, освободите все ваши ресурсы»)
- Эти коллекционные пожарные события («о, мой, смотри, кто-то просто добавил/удалил»/изменил элемент ').
- Во время запуска кода обработчика событий клиента этот код решает удалить объект, который только что отправил событие (что, семантически, является правильным действием, например: теперь коллекция не содержит объект интереса для меня больше, поэтому я избавлюсь от него).
Это, конечно, наносит ущерб отправляющим объектам.
В настоящее время «решение» заключается в защите (т.е. запретить) размещени в то время как события увольняют:
private bool m_AllowDisposal;
private void MeFiringEvents()
{
m_AllowDisposal = false;
// Fire event
if (m_MyEventHandlers != null)
{
m_MyEventHandlers(...);
}
m_AllowDisposal = true;
}
public void IDisposable.Dispose()
{
if (m_AllowDisposal)
{
// Dispose resources, set members to null, etc
}
}
Как вы можете видеть, это не реальное решение, поскольку распоряжение для отправителя мероприятия эффективно блокируется во время обработки кода клиента.
Любое другое решение, которое я мог придумать бы по линии
- После каждого выстрела событий, проверить, является ли удаление (или любой другой «плохой» модификация объекта) произошло в обработчик событий клиента код.
- Выйдите из кода отправителя (который может быть глубоко вложен до тех пор, пока он не достигнет срабатывания события) защитным способом.
Интересно, что я не нашел полезной информации по этой теме в сети, хотя это похоже на общий showstopper.
Возможно, у вас есть идея.
Спасибо за ваше внимание,
Christian
«Это, конечно, наносит ущерб отправляющим объектам». Почему конечно"? Вы не можете это исправить? – Henrik
Ну, если сразу после вызова обработчиков событий вашего клиента все ваши переменные-члены были установлены в нуль (по вашему собственному методу размещения), это означает бесконечность if (member! = Null), что кажется довольно неудобным. – 7enderhead