C#의 중복 이벤트 구독을 피하십시오.
-
03-07-2019 - |
문제
중복 이벤트 구독을 피하는 가장 좋은 방법을 어떻게 제안 하시겠습니까? 이 코드 라인이 두 곳에서 실행되면 이벤트는 두 번 실행됩니다. 타사 이벤트가 두 번 구독하는 것을 피하려고 노력하고 있습니다.
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 클래스의 소스를 소유하고 있다면 TheEvent의 호출 목록에 액세스 할 수 있습니다. 이벤트를 위해 자신의 추가 액세서를 구현하고 추가하기 전에 확인할 수 있습니다.
그러나 나는 당신의 접근 방식도 괜찮다고 생각합니다.
나는 하나의 세부 사항을 제외하고 당신의 접근 방식을 사용합니다. 가입자 또는 theObject의 새 인스턴스를 만들 때 이벤트를 구독해야한다고 생각합니다. 따라서, 당신이 필요한 것은 올바른 물체를 처분 한 후에주의 깊게 시청하기 만하면됩니다 (Patten은 편리한 솔루션입니다).
당신은 당신이 타사 이벤트를 사용한다고 언급했는데, 이는 조언을받은대로 메소드 추가/제거에 대한 자신의 실현을 제공 할 수 없음을 의미합니다. 그러나 자신의 이벤트가있는 자신의 수업에서는 문제를 해결하기 위해 이벤트를위한 추가/제거 방법의 자신의 실현을 정의해야합니다.