c#事件传递类到第三层类

  • 本文关键字:三层 事件 c# events
  • 更新时间 :
  • 英文 :


好的,这是我的用例。

我已经编写了一个MMO服务器游戏引擎,我现在的架构方式主要是EDA。当服务器从客户端接收数据包时,核心服务器发布一个事件,其他类订阅该事件,该事件在EventType e参数中携带数据包有效负载。消息的头在消息的第一个字节中有一个头,字节的前半部分携带按位信息,确定哪个类应该接收消息并对其进行处理,而字节的后半部分确定类中的哪个方法需要处理消息。而那些不应该处理任何事情的类只会丢弃它。

这个求值是通过每个类上的一系列if语句来完成的,首先问…If (headervalue != myexpectedheader) return;…为了清楚起见,它实际上是一个double if(小于)||(大于)返回;因为可能属于我的头值集合是一个范围,因为字节的前半部分指向类,而字节的后半部分指向方法,所以类不能真正求出"什么是我的"而是"什么不是我的"为了让if语句保持在条件设置的顶部,因为它更有可能不是我的,而不是我的。这工作得很好。评估头文件并确定有效负载的类完美地完成了这些工作,而那些不应该这样做的类……不。这部分我不需要帮助,只是让我解释一下让别人理解。

因为这是一个MMO服务器,在网络密集的活动中,可能会接收、处理和响应数千个用户,每秒可能发送数百个数据包,我担心的是有大量的类对从无数客户端接收的每条消息执行条件评估。

再加上很可能90%到95%的收到的消息应该由一个或两个类拾取这一事实。因此,大量的系统时间将浪费在评估上,而不是为我。每个类,但也特别因为90%的消息可能会去最常用的类。

因此,我正在尝试构建一个消息路由器,该路由器将订阅核心服务器类上的传入消息事件,执行"哪个类";每条消息只执行一次条件计算,并在计算后发布新事件,这样只有一两个真正需要使用该事件的其他类可以订阅该新事件,从而消除了无数次浪费的计算,这些计算基本上会导致";If (not for me) return;">

问题的范围实际上总结在下面,上面所写的内容并不在实际问题的范围内,它只是对如何进行评估的解释,以及为什么这个用例使问题相关。

我有一个类a,它有一个主要事件。那件事会很快发生。我有大量的C类需要潜在地从a类事件接收信息。然而,由于我有大量的C类订阅者,我想创建一个B类中间人作为事件路由器,以减少a类直接订阅者的数量(从而减少系统开销)

我希望类B订阅类A,类C订阅类B,最终结果是正确的类C有效地从类A中获取了事件。

我已经编写了对事件进行排序的逻辑,但是我不知道如何编写传递事件,以便类C订阅者通过侦听类B事件来消费类A事件。

我不确定我是否正确理解了这个问题,但是从某个地方开始,这里有一个我认为您要求的示例(参见fiddle for test run: https://dotnetfiddle.net/abEgV4):

public class Program
{
public static void Main()
{
var source = new ClassA();
var middleman = new ClassB(source);
var subscribers = Enumerable.Range(0, 10)
.Select(_ => new ClassC(middleman))
.ToArray();

Console.WriteLine("Fire 1!");
source.FireEvent();
Console.WriteLine("Fire 2!");
source.FireEvent();
Console.WriteLine("Fire 3!");
source.FireEvent();
Console.WriteLine("Fire 4!");
source.FireEvent();
Console.WriteLine("Fire 5!");
source.FireEvent();
}
}
class ClassA
{
public delegate void SomeAEventHandler(object sender, string msg);
public event SomeAEventHandler SomeAEvent;

public void FireEvent()
{
SomeAEvent?.Invoke(this, "Event A fired");
}
}
class ClassB
{
public event ClassA.SomeAEventHandler SomeAEvent;
private ClassA _eventSource;

public ClassB(ClassA eventSource)
{
_eventSource = eventSource;
eventSource.SomeAEvent += SomeAEventHappened;
}

private void SomeAEventHappened(object sender, string msg)
{
var rnd = new Random().Next(10);
if (rnd % 2 == 0)
{
// Instead of 'this' use 'sender' if needed
SomeAEvent?.Invoke(this, msg);
}
}
}
class ClassC
{
private readonly ClassB _myMiddleman;
public ClassC(ClassB middleman)
{
_myMiddleman = middleman;
middleman.SomeAEvent += SomeAEventHappened;
}

private void SomeAEventHappened(object sender, string msg)
{
Console.WriteLine("ClassC got an event!");
}
}

这样就能解决问题了吗?你能详细说明还缺什么吗?

最新更新