자세 한 설명 c\#이벤트 버스
이벤트 버스 는 게시-구독 모드 에 대한 일종 의 실현 으로 집중 식 이벤트 처리 체제 로 서로 다른 구성 요소 간 에 서로 통신 할 수 있 고 서로 의존 하지 않 아 도 되 며 결합 을 해제 하 는 목적 을 달성 할 수 있 습 니 다.
이벤트 버스 구현
EventBus 는 이벤트 사전 을 유지 합 니 다.게시 자,구독 자 는 이벤트 버스 에서 이벤트 인 스 턴 스 를 가 져 오고 게시,구독 작업 을 수행 합 니 다.이벤트 인 스 턴 스 는 이벤트 처리 프로그램 을 유지 하고 실행 합 니 다.절 차 는 다음 과 같다.
이벤트 기본 클래스 정의
이벤트 인 스 턴 스 는 이벤트 버스 에 등록 하고 기본 클래스 를 정의 하여 이벤트 버스 를 관리 해 야 합 니 다.코드 는 다음 과 같 습 니 다.
/// <summary>
///
/// </summary>
public abstract class EventBase{ }
이벤트 인 스 턴 스 는 등 록 된 이벤트 처리 프로그램 을 관리 하고 실행 해 야 합 니 다.서로 다른 이벤트 매개 변수 에 적응 하기 위해 서 는 일반적인 파 라 메 터 를 사용 할 수 없습니다.코드 는 다음 과 같 습 니 다:
/// <summary>
///
/// </summary>
/// <typeparam name="T"></typeparam>
public abstract class PubSubEvent<T> : EventBase where T : EventArgs
{
protected static readonly object locker = new object();
protected readonly List<Action<object, T>> subscriptions = new List<Action<object, T>>();
public void Subscribe(Action<object, T> eventHandler)
{
lock (locker)
{
if (!subscriptions.Contains(eventHandler))
{
subscriptions.Add(eventHandler);
}
}
}
public void Unsubscribe(Action<object, T> eventHandler)
{
lock (locker)
{
if (subscriptions.Contains(eventHandler))
{
subscriptions.Remove(eventHandler);
}
}
}
public virtual void Publish(object sender, T eventArgs)
{
lock (locker)
{
for (int i = 0; i < subscriptions.Count; i++)
{
subscriptions[i](sender, eventArgs);
}
}
}
}
이벤트 매개 변수 기본 클래스 정의이벤트 매개 변수 기본 클래스 는 EventArgs 를 계승 하고 일반적인 매개 변 수 를 사용 하여 서로 다른 매개 변수 유형 에 적응 하 며 이러한 예화 가 허용 되 지 않 습 니 다.코드 는 다음 과 같 습 니 다:
/// <summary>
///
/// </summary>
/// <typeparam name="T"></typeparam>
public abstract class PubSubEventArgs<T> : EventArgs
{
public T Value { get; set; }
}
정의 EventBusEventBus 는 이벤트 인 스 턴 스 관리 만 제공 하고 구체 적 인 이벤트 처리 프로그램의 실행 은 이벤트 인 스 턴 스 가 스스로 책임 집 니 다.사용 편 의 를 위해 구조 함 수 는 자동 으로 이벤트 등록 기능 이 있 으 며,여러 프로그램 집합 이 있 을 때 bug 가 있 을 수 있 습 니 다.코드 는 다음 과 같 습 니 다:
/// <summary>
///
/// </summary>
class EventBus
{
private static EventBus _default;
private static readonly object locker = new object();
private Dictionary<Type, EventBase> eventDic = new Dictionary<Type, EventBase>();
/// <summary>
/// ,
/// </summary>
public static EventBus Default
{
get
{
if (_default == null)
{
lock (locker)
{
// ,
if (_default == null)
{
_default = new EventBus();
}
}
}
return _default;
}
}
/// <summary>
/// , EventBase
/// </summary>
public EventBus()
{
Type type = typeof(EventBase);
Type typePubSub = typeof(PubSubEvent<>);
Assembly assembly = Assembly.GetAssembly(type);
List<Type> typeList = assembly.GetTypes()
.Where(t => t != type && t != typePubSub && type.IsAssignableFrom(t))
.ToList();
foreach (var item in typeList)
{
EventBase eventBase = (EventBase)assembly.CreateInstance(item.FullName);
eventDic.Add(item, eventBase);
}
}
/// <summary>
///
/// </summary>
/// <typeparam name="TEvent"> </typeparam>
/// <returns></returns>
public TEvent GetEvent<TEvent>() where TEvent : EventBase
{
return (TEvent)eventDic[typeof(TEvent)];
}
/// <summary>
///
/// </summary>
/// <typeparam name="TEvent"></typeparam>
public void AddEvent<TEvent>() where TEvent : EventBase ,new()
{
lock (locker)
{
Type type = typeof(TEvent);
if (!eventDic.ContainsKey(type))
{
eventDic.Add(type, new TEvent());
}
}
}
/// <summary>
///
/// </summary>
/// <typeparam name="TEvent"></typeparam>
public void RemoveEvent<TEvent>() where TEvent : EventBase, new()
{
lock (locker)
{
Type type = typeof(TEvent);
if (eventDic.ContainsKey(type))
{
eventDic.Remove(type);
}
}
}
}
이벤트 버스 사용이벤트 및 이벤트 매개 변수
이벤트 버스 를 사용 하기 전에 이벤트 와 이벤트 파 라 메 터 를 정의 해 야 합 니 다.사용 할 때 게시 자,구독 자 도 이벤트 유형 과 이벤트 매개 변수 유형 을 알 아야 합 니 다.코드 는 다음 과 같 습 니 다:
/// <summary>
/// -TestAEvent,
/// </summary>
public class TestAEvent: PubSubEvent<TestAEventArgs>
{
public override void Publish(object sender, TestAEventArgs eventArgs)
{
lock (locker)
{
for (int i = 0; i < subscriptions.Count; i++)
{
var action= subscriptions[i];
Task.Run(() => action(sender, eventArgs));
}
}
}
}
/// <summary>
/// -TestAEventArgs
/// </summary>
public class TestAEventArgs : PubSubEventArgs<string> { }
/// <summary>
/// -TestBEvent
/// </summary>
public class TestBEvent : PubSubEvent<TestBEventArgs> { }
/// <summary>
/// -TestBEventArgs
/// </summary>
public class TestBEventArgs : PubSubEventArgs<int> { }
주:TestAEvent 에 서 는 이벤트 발표 논 리 를 재 작성 하여 모든 이벤트 가 작업 에서 실 행 됩 니 다.게시 자 정의
게시 자 는 이벤트 버스 를 통 해 이벤트 인 스 턴 스 를 가 져 옵 니 다.인 스 턴 스 에서 이 벤트 를 발표 합 니 다.코드 는 다음 과 같 습 니 다.
class Publisher
{
public void PublishTeatAEvent(string value)
{
EventBus.Default.GetEvent<TestAEvent>().Publish(this, new TestAEventArgs() { Value=value});
}
public void PublishTeatBEvent(int value)
{
EventBus.Default.GetEvent<TestBEvent>().Publish(this, new TestBEventArgs() { Value = value });
}
}
구독 자 정의구독 자 는 이벤트 버스 를 통 해 이벤트 인 스 턴 스 를 가 져 옵 니 다.인 스 턴 스 에서 이 벤트 를 구독 합 니 다.코드 는 다음 과 같 습 니 다.
class ScbscriberA
{
public string Name { get; set; }
public ScbscriberA(string name)
{
Name = name;
EventBus.Default.GetEvent<TestAEvent>().Subscribe(TeatAEventHandler);
}
public void TeatAEventHandler(object sender, TestAEventArgs e)
{
Console.WriteLine(Name+":"+e.Value);
}
}
class ScbscriberB
{
public string Name { get; set; }
public ScbscriberB(string name)
{
Name = name;
EventBus.Default.GetEvent<TestBEvent>().Subscribe(TeatBEventHandler);
}
public void Unsubscribe_TeatBEvent()
{
EventBus.Default.GetEvent<TestBEvent>().Unsubscribe(TeatBEventHandler);
}
public void TeatBEventHandler(object sender, TestBEventArgs e)
{
Console.WriteLine(Name + ":" + e.Value);
}
}
실제 사용코드 는 다음 과 같 습 니 다:
class Program
{
static void Main(string[] args)
{
Publisher publisher = new Publisher();
ScbscriberA scbscriberA = new ScbscriberA("scbscriberA");
ScbscriberB scbscriberB1 = new ScbscriberB("scbscriberB1");
ScbscriberB scbscriberB2 = new ScbscriberB("scbscriberB2");
publisher.PublishTeatAEvent("test");
publisher.PublishTeatBEvent(123);
scbscriberB2.Unsubscribe_TeatBEvent();
publisher.PublishTeatBEvent(12345);
Console.ReadKey();
}
}
실행 결과:scbscriberB1:123
scbscriberB2:123
scbscriberA:test
scbscriberB1:12345
총결산
이 이벤트 버스 는 기본 기능 만 제공 하고 이 루어 진 게시 자 와 구독 자의 결합 을 해제 하 며 게시 자,구독 자 는 이벤트 에 만 의존 하고 서로 의존 하지 않 습 니 다.
제 가 사건 버스 에 대한 이해 가 아직 부족 하 다 고 생각 합 니 다.여러분 이 토론 하 시 는 것 을 환영 합 니 다!
이상 은 c\#이벤트 버스 의 상세 한 내용 입 니 다.c\#이벤트 버스 에 관 한 자 료 는 다른 관련 글 을 주목 하 십시오!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
C#Task를 사용하여 비동기식 작업을 수행하는 방법라인이 완성된 후에 이 라인을 다시 시작할 수 없습니다.반대로 조인(Join)만 결합할 수 있습니다 (프로세스가 현재 라인을 막습니다). 임무는 조합할 수 있는 것이다. 연장을 사용하여 그것들을 한데 연결시키는 것이...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.