【问题标题】:Subscribe to an event from an object created at run time从运行时创建的对象订阅事件
【发布时间】:2019-04-08 21:59:03
【问题描述】:

我有一个 Server 类,它在接收到新连接时在运行时创建一个 ClientHandler 对象。在 ClientHandler 内部,我需要在收到特定消息时触发 clientEvent。在我的 Form 类中,我引用了 Server 类,但我需要订阅 ClientHandler 对象中的 clientEvent。但是,该对象在设计时还不存在。如何订阅?

我在服务器中创建了一个订阅 clientEvent 的事件处理程序,它引发了另一个 serverEvent。在 Form 类中,我订阅了 serverEvent。这样我就间接地收听了clientEvent。但我相信有更好的方法来做到这一点。

public delegate void SomeEvent(string message);

public class Server
{
  public ClientHandler clientHandler;
  public event SomeEvent serverEvent;
  // callback function when new connection received
  public void on_connected()
  {
    clientHandler = new ClientHandler(...)
    clientHandler.clientEvent += ClientEventHandler;
    }
  public void ClientEventHandler(string message)
  {
    serverEvent?.Invoke(message)
  }
}

public class ClientHandler
{
  public event SomeEvent clientEvent;
  // callback when message is read
  void ReadCallback(...)
  {
    ...
    // Some message received
    clientEvent?.Invoke("Message received: " + someMessage);
  }

public partial class From1 : Form
{
  public Form1()
  {
   Server server = new Server(...);
   server.serverEvent += serverEventHandler;
   ...
  }
  private void serverEventHandler(string message)
  {
   // do something with message
  }
}

【问题讨论】:

    标签: c# events tcplistener


    【解决方案1】:

    这种方式没有任何问题,只要您确定在移除孩子时取消订阅该事件即可。

    以下是解决此问题的 3 种主要方法

    1. Parent订阅child事件退订child em> 被移除
    2. parentreference传递给child,在parent上调用事件 em> 需要时。这可以更整洁(有时)并且更易于管理。
    3. 通过事件聚合器之类的东西使用解耦消息,它将事件发布者转发到订阅者。它们是解耦的,因为它们不需要相互了解,并且可以一起跳过父节点

    【讨论】:

    • 感谢您的回答!如果我坚持目前的方法,您认为我应该在哪里取消订阅 Server 类中的子事件?
    • @KaijunFeng,当所有连接的客户端断开连接时,您会将所有连接的客户端保留在列表中,您将取消注册处理程序
    猜你喜欢
    • 2018-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-09
    • 2022-10-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多