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

JSON.stringify(collectionNames).includes(JSON.stringify(sourceNames)) ?  array.push(collection[i]) : null

Вот как я это сделал.

42
задан Glen T 15 December 2008 в 17:28
поделиться

3 ответа

Если Вы говорите о событии на классе, для которого у Вас есть доступ к источнику тогда, Вы могли поместить защиту в конечном счете определение.

private bool _eventHasSubscribers = false;
private EventHandler<MyDelegateType> _myEvent;

public event EventHandler<MyDelegateType> MyEvent
{
   add 
   {
      if (_myEvent == null)
      {
         _myEvent += value;
      }
   }
   remove
   {
      _myEvent -= value;
   }
}

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

РЕДАКТИРОВАНИЕ см. комментарии о том, почему вышеупомянутый код является плохой идеей и не ориентированный на многопотоковое исполнение.

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

не уже подписанный

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

Редактирование (после того, как принятый): На основе комментария от @Glen T (submitter вопроса) код для принятого решения, с которым он пошел, находится в клиентском классе:

if (alreadySubscribedFlag)
{
    member.Event += new MemeberClass.Delegate(handler);
}

, Где alreadySubscribedFlag является членской переменной в клиентском классе, который отслеживает первую подписку к определенному событию. Люди, смотрящие на первый фрагмент кода здесь, примите во внимание комментарий @Rune - это не хорошая идея изменить поведение подписки на событие неочевидным способом.

РЕДАКТИРОВАНИЕ 31.07.2009: см. комментарии от @Sam Saffron. Как я уже заявил, и Sam соглашается, что первая методика, представленная здесь, не является разумным способом изменить поведение подписки события. Потребители класса должны знать о его внутренней реализации для понимания его поведения. Не очень хороший.
@Sam Saffron также комментирует о потокобезопасности. Я предполагаю, что он обращается к возможному состоянию состязания, где два подписчика (близко к) одновременно пытаются подписаться, и они могут оба закончить тем, что подписались. Блокировка могла использоваться для улучшения этого. Если Вы планируете изменить способ, которым подписка события работает тогда, я сообщаю, что Вы чтение о том, как заставить подписку добавить/удалить свойства, ориентированные на многопотоковое исполнение .

36
ответ дан Community 23 September 2019 в 13:29
поделиться

Поскольку другие показали, можно переопределить добавить/удалить свойства события. С другой стороны, можно хотеть угробить событие и просто иметь класс, берут делегата в качестве аргумента в его конструкторе (или некоторый другой метод), и вместо того, чтобы запустить событие, звонят предоставленному делегату.

События подразумевают, что любой может подписаться на них, тогда как делегат один метод, который можно передать классу. Вероятно, будет менее удивительным пользователю Вашей библиотеки тогда, если Вы только будете использовать события, когда Вы на самом деле wnat one-many семантика она обычно предлагает.

7
ответ дан jalf 23 September 2019 в 13:29
поделиться

Необходимо было бы или сохранить отдельный флаг, указывающий, подписались ли Вы или, если Вы управляете MemberClass, обеспечьте реализации добавления и удалите методы для события:

class MemberClass
{
        private EventHandler _event;

        public event EventHandler Event
        {
            add
            {
                if( /* handler not already added */ )
                {
                    _event+= value;
                }
            }
            remove
            {
                _event-= value;
            }
        }
}

, Чтобы решить, был ли обработчик добавлен, необходимо будет сравнить Делегатов, возвращенных из GetInvocationList () и на _event и на значении.

3
ответ дан Andrew Kennan 23 September 2019 в 13:29
поделиться
Другие вопросы по тегам:

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