2013-05-28 2 views
0

Я привязываюсь к событию Exit Process. У меня есть флажок для этого процесса для этого события, который определяет, что происходит, когда выполняется Exited-событие. Если я установил флажок во время выполнения процесса, он получит Process и добавит событие Exited. Если процесс не запущен, он запускает процесс и добавляет событие «Выход». Если флажок снят, независимо от того, запущен ли процесс или нет, я ничего не делаю.Убедитесь, что только один делегат связан с событием?

Моя проблема заключается в том, что если процесс запущен, и я проверяю флажок (он получает событие), снимите флажок (ничего не происходит по дизайну) и перепроверьте поле, тогда процесс получит ДВА ВЫХОДА событий (что являются тем же самым методом). Если у меня есть объект Process, как я могу добавить событие Exited, если оно уже есть?

+1

Вы можете разместить соответствующий код для того, как зарегистрировать обработчик для события возбужденном? –

+0

Кажется подозрительным, что вам нужно заглянуть в делегат, чтобы определить, сколько регистраторов зарегистрировано. Возможно, вы можете зарегистрироваться только один раз, а затем внутри функции определить, следует ли запускать на основе текущего значения флажка? – deepee1

+0

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

ответ

1

Вы отвлекаете события от делегатов с помощью оператора -=.

Так же, как вы могли бы сделать это, чтобы связать событие делегата:

EventHandler foo = new EventHandler(this._onClick) 
myButton.Click += foo; 

Вы также мог бы это сделать, если вы держите эту ссылку где-то:

myButton.Click -= foo; 

И тогда, когда событие срабатывает, он больше не вызывает foo.

Что вы, вероятно, делаете, когда флажок получает проверяется, что-то вроде этого:

foo.Exited += new EventHandler(your_method); 

Таким образом, каждый раз, когда вы установите флажок, вы получите новый обработчик привязанный к событию. Используйте только один обработчик. Таким образом, когда флажок не установлен, вы можете указать -= делегат, с которым вы связались раньше.

Edit: поскольку все, что вы хотите, чтобы сохранить метод, на который ссылается делегат, чтобы не делать ничего, почему бы не связать делегата на мероприятие в какой-то момент, кроме события проверки, а затем использовать состояние флажка в методе, чтобы выбрать, запускаете ли вы весь метод или останавливаете его с преждевременным возвратом?

+0

Когда флажок снят, событие все равно должно быть привязано к нему. Когда флажок будет проверен, я надеюсь не зарегистрировать второй EventHandler. –

+1

@Corey Затем добавьте на уровне класса логическое значение, указывающее, что событие было назначено. Если он установлен, не назначайте его снова. –

0

Чтобы получить массив всех делегатов, подписавшихся на приглашение, просто используйте метод GetInvoacationList. Оттуда вы можете проверить его длину или перебрать по нему, чтобы проверить, сколько/которое делегирует событие.

Delegate[] delegates = MyEvent.GetInvocationList(); 

Основываясь на том, что вы на самом деле пытаетесь сделать, похоже, что вы можете просто что-то сделать;

if (MyEvent.GetInvocationList().Length > 0) 

или

if (MyEvent.GetInvoationList().Contains(referenceToMyDelegate)) 
+0

Это не мое событие. Я не могу получить доступ к списку вызовов Exited Invocation. –

0

Попробуйте это:

delegate void MyDelegate(string message); 

class Foo 
{ 
    MyDelegate _delegate = null; 
    int _count = 0; 

    public event MyDelegate MySingleDelegateEvent 
    { 
     add 
     { 
      if (_count == 0) 
      { 
       _delegate += value; 
       _count++; 
      } 
     } 
     remove 
     { 
      if (_delegate != null) 
      { 
       _delegate -= value; 
       _count--; 
      } 
     } 
    } 
} 
0

Если вы должны всмотреться в случае, вы можете использовать отражение:

class Program 
{ 
    static void Main(string[] args) 
    { 
     var car = new Car(); 
     car.Stopped += car_Stopped; 
     var evt = car.GetType().GetEvent("Stopped"); 
     if(evt == null) //evt will be null if nothing is registered to the event 
      car.Stopped += car_Stopped; 

     car.Stop(); //Prints 'Stopped!' only once 

     Console.ReadLine(); 
    } 

    static void car_Stopped(object sender, EventArgs e) 
    { 
     Console.WriteLine("Stopped!"); 
    } 
} 

class Car 
{ 
    public event EventHandler<EventArgs> Stopped; 
    protected void OnStopped() 
    { 
     var temp = Stopped; 
     if(temp != null) 
      Stopped(this, new EventArgs()); 
    } 
    public void Stop() 
    { 
     OnStopped(); 
    } 
} 
+0

Мне нравится этот подход, но что-то об использовании Reflection on types в библиотеке .Net просто кажется взломанным. Тем не менее, это кажется выполнимым по сравнению с другими ответами. –

+0

@Corey Просто отпишитесь (- =) в строке, непосредственно предшествующей подписке (+ =). Он не будет бросать, если вы отмените подписку на событие, которое вы не подписали ранее. –

Смежные вопросы