c# - 通过多个消费者和事件处理程序使用存储的事件

标签 c# events reactivex

我目前正在使用这种模式来处理来自某些事件接收器(例如企业服务总线、队列、EventStore)的事件。这个想法是在一个列表中实例化几个 IEventWorker(参见下面的具体示例)并传递事件,例如,通过在遍历列表时调用每个实例的 HandleEvent 方法。这是 IEventWorkers 具体的基本代码:

public class EventWorker : IEventWorker 
{
    private Dictionary<Type, Action<object>> CreateEventHandlerMapping()
    {
        return new Dictionary<Type, Action<object>>
        {
        {typeof (Event1), o => Handle(o as Event1)},
        {typeof (Event2), o => Handle(o as Event2)},
        };
    }

    private void Handle(Event1 eventToHandle)
    {

    }

    private void Handle(Event2 eventToHandle)
    {

    }

    public void HandleEvent(IEvent evt)
    {
        var eventType = evt.GetType();
        if (_eventHandlerMapping.ContainsKey(eventType))
        {
        _eventHandlerMapping[eventType](evt);
        }
    }
}

也许有更好的方法来做到这一点?

附言:

This非常接近我想要实现的目标。我不完全理解 ObserverRegistry 如何分发来自事件队列等的所有事件。

最佳答案

您的问题本质上相当广泛;也许有点太多了。我鼓励您完善它。

但是,您要求潜在的改进,我至少可以想到一件足够具体的事情:

  • 为了类型安全,您可以使用双重分派(dispatch)而不是类型转换。

参见 the visitor pattern了解更多信息。在您的情况下,您将在 IEvent 上创建类似 Accept 的方法,并在 HandleEvent 中调用它:

public void HandleEvent(IEvent evt)
{
    evt.Accept(this);
}

事件类型的接受方法如下所示:

public void Accept(IEventWorker worker)
{
    worker.Handle(this);
}

(虽然这仍然是一个虚拟调用,但请注意现在静态选择了处理程序方法重载。这与您现有的运行时字典查找形成对比。)

IEventWorker 接口(interface)会为每个事件类型指定一个方法,这相当于“注册”它们,尽管这次是以类型安全的方式进行的。请注意,这会改变他们对您的实现的访问级别,这很好。

然后您可以完全删除映射字典;您现在正在使用该类的虚拟表来达到相同的效果。

我不会跳到也声称性能改进(如果它在您的场景中甚至很重要),但如果它很重要,您可能想要测试并查看(您至少应该期望更好的性能)。

关于c# - 通过多个消费者和事件处理程序使用存储的事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35196573/

相关文章:

c# - 在 elasticsearch NEST 客户端中使用地理点索引未映射/动态映射的文档

c# - 如何在 C# 中分配超过 MaxInteger 字节的内存

c# - 处理 DataReceivedEventArgs 事件未触发

c# - 在 Windows 服务程序中记录事件

c# - 动态 Linq 按变量排序

javascript - 目前 html5 video-Tag 的 Loading-Event

javascript - JavaScript 中的事件检查

Rxjs - 如何在通知 UI 错误的同时重试错误的可观察对象

android - 如何在 Android 上使用 RxJava (+ retrofit2) 执行 3 个以上的并行 http 请求

java - 如何创建订阅可观察对象的BehaviorSubject?