【问题标题】:.NET Core 3.1 - Scoped service - Event handler invokes multiple times.NET Core 3.1 - 范围服务 - 事件处理程序多次调用
【发布时间】:2020-06-26 10:28:39
【问题描述】:

我在.net core 3.1中创建了一个应用程序,其中有一个单例接口及其实现类,用于接收TCP/IP套接字消息。类中有一个事件处理程序,一旦在套接字上收到消息就会调用它。

公共类 IncomingMessageHandler : IIncomingMessageHandler
{
    公共事件 EventHandler OnMessageReceived;

    私人无效InvokeMessageRecived(对象发件人,字符串消息)
    {
        this.OnMessageReceived?.Invoke(this, message);
    }
}

还有另一个服务TransactionService 类为接口IIncomingMessageHandler 注入了依赖项并订阅OnMessageReceived

public TransactionService(IIncomingMessageHandler incomingMessageHandler)
{
    this.incomingMessageHandler = 传入消息处理程序;
    this.incomingMessageHandler.OnMessageReceived += this.IncomingMessageHandler_OnMessageReceived;
}

在这个类中,我正在启动事务,一旦事务开始,我将在IncomingMessageHandlerOnMessageReceived 调用中接收消息,我将消息存储到列表中以供进一步处理。

现在TransactionService 是Scoped 服务类,将为每个API 请求创建新对象,现在如果有多个请求,每个TransactionService 将订阅OnMessageReceived,它会多次调用,因为有是多个对象启动并覆盖消息列表。

由于其他一些限制,我无法将 TransactionService 注册为单例。

有没有其他方法可以只为特定的服务对象调用OnMessageReceived

我已尝试取消订阅OnMessageReceived,但仍然会同时出现多个 API 请求。

【问题讨论】:

  • 你有一个队列系统,你有来自多个来源的输入和一个 API 来处理数据。您必须像处理任何其他排队系统一样处理此问题。见维基:en.wikipedia.org/wiki/Queue_management_system
  • 感谢您的评论,我不确定这是否与排队有关,而且我无法限制每个人的 API 访问权限并应用任何队列机制。
  • 您所描述的是一个队列系统,它具有类型(FIFO/优先级)、单例/并行和锁定(如果需要)。

标签: c# .net-core dependency-injection event-handling asp.net-core-webapi


【解决方案1】:

由于您绑定到一个事件并且在完成时没有解除绑定,它会导致一些内存泄漏 - TransactionService 的实例存在于其他引用中并且不能被 GC'd。您应该让TransactionService 实现IDisposable 并在Dispose 方法中解除绑定。这会从 IncomingMessageHandler 中的事件中删除引用,并且您不会有重复的调用。

除此之外:我尝试了一些非常相似的方法,实际上我发现使用响应式扩展可以得到更好的整体模式。

【讨论】:

  • 我尝试使用 IDisposable 处理 TransactionService,现在处理了 TransactionService。但是,当我当时尝试执行并发 API 请求时,它会执行重复调用并覆盖上一次调用中现有的存储详细信息。
  • @MohsinTolat 这是一个单独的问题,你的模式有点缺陷
  • 是的,我同意你的看法@Daniel A. White,我还有什么可以用来解决这个缺陷的吗?
猜你喜欢
  • 1970-01-01
  • 2018-08-18
  • 1970-01-01
  • 2017-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-25
相关资源
最近更新 更多