Вопрос

Как бы вы предложили лучший способ избежать дублирования подписок на мероприятия?если эта строка кода выполняется в двух местах, событие будет запущено дважды.Я пытаюсь избежать двойной подписки на сторонние события.

theOBject.TheEvent += RunMyCode;

В моем установщике делегата я могу эффективно запустить это...

theOBject.TheEvent -= RunMyCode;
theOBject.TheEvent += RunMyCode;

но лучший ли это способ?

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

Решение

Я думаю, что наиболее эффективный способ - сделать ваше событие свойством и добавить к нему блокировки параллелизма, как в Пример :

private EventHandler _theEvent;
private object _eventLock = new object();
public event EventHandler TheEvent
{
    add
    {
        lock (_eventLock) 
        { 
            _theEvent -= value; 
            _theEvent += value; 
        }
    }
    remove
    {
        lock (_eventLock) 
        { 
           _theEvent -= value; 
        }
    }
}

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

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

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            MyObject my = new MyObject();
            my.Changed += new EventHandler(my_Changed);
            my.Changed += new EventHandler(my_Changed1);

            my.Update();
            Console.ReadLine();
        }

        static void my_Changed(object sender, EventArgs e)
        {
            Console.WriteLine("Hello");
        }
        static void my_Changed1(object sender, EventArgs e)
        {
            Console.WriteLine("Hello1");
        }
    }
    public class MyObject
    {
        public MyObject()
        {
        }
        private EventHandler ChangedEventHandler;
        public event EventHandler Changed
        {
            add
            {
                ChangedEventHandler = value;
            }
            remove
            {
                ChangedEventHandler -= value;
            }
        }
        public void Update()
        {
            OnChanged();
        }

        private void OnChanged()
        {
            if (ChangedEventHandler != null)
            {
                ChangedEventHandler(this, null);
            }
        }
    }
}

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

Таким образом, ваш подход к отмене подписки и подписке правильный.

Спасибо

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

Однако я думаю, что ваш подход тоже подойдет.

Я использую ваш подход, за исключением одной детали. Я думаю, что события должны быть подписаны, когда вы создаете новый экземпляр подписчика или theObject, это делает код более прямым. Таким образом, все, что вам нужно, это просто внимательно следить за правильной утилизацией предметов (для этого удобно использовать утилиту «Паттен»).

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top