从事件处理程序访问对象



我正在使用外部类打开与远程应用程序的连接。此类从通过处理程序处理的远程应用程序接收数据。

对于这个处理程序,我添加了几个检查来解析不同方法中的数据。但是,我现在停留在需要再次访问该对象的地步,该对象触发了事件以在其上调用方法。我确信这是一个非常基本的问题,但我才刚刚从 OOP 开始。

public static void Main(string[] args) {
    IBattleNET b = new BattlEyeClient(loginCredentials);
    b.MessageReceivedEvent += HandleMessage;   
    b.Connect();
} 
private static void HandleMessage(BattlEyeMessageEventArgs args) {
    //call a method to analyze data parse
    PlayerList(args.Message);
}
private static void parsePlayerList(string playerList) { 
    // At this point I need to access the object b again to to call a method
}

修改处理程序以传递对象:

b.MessageRecievedEvent += (e) => HandleMessage(b, e);
....
private static void HandleMessage(IBattleNet b, BattleMessageEventArgs args) {
....

lambda 表达式将参数存储为 'e',然后通过同时传递对象和 'e' 来调用 HandleMessage。

但是,Pickles提出的约定是更好的做法,如果您可以访问并且可以在IBattleNET中更改事件本身。

通常,事件使用签名中有两个参数的委托。一个对象"source"参数表示发送方,"args"参数表示事件参数。

如果您有权访问MessageReceivedEvent则应更改委托以包含表示发件人的"object"参数。然后,您的HandleMessage方法将如下所示:

private static void HandleMessage(object sender, BatlEyeMessageEventArgs args)
{
        var battleNet = sender as IBattleNet;
        if (battleNet == null)
           return;
        battleNet.Foo();
        PlayerList(args.Message);
}

由于您的传入方法是静态的,因此您会遇到一些挑战,特别是当多条消息在非常短的时间内到达时会发生什么?如果存储以后要重用的信息,则很容易被收到的下一条消息覆盖。

在这种情况下,我通常会创建一个负责解析和处理传入消息的新类,并在事件处理程序中创建该类的新实例,并将事件参数传递给构造函数。

从那时起,消息的所有处理都发生在类实例中。

例如,你可以有一个这样的类来存储消息,验证它,然后对它执行一些分析:

public class PlayerListEvent
{
    private string m_sMessage;
    public PlayerListEvent(String sMessage)
    {
        m_sMessage = sMessage;
    }
    public Boolean MessageIsValid()
    {
        // Validate the incoming message
        return true;
    }
    public void ParseMessage() {
        // Perform the message parsing
    }
}

您可以将所有传入的消息存储在列表(或类或其他存储机制)中,以便可以根据需要处理它们:

    private static System.Collections.Generic.List<PlayerListEvent> m_cReceivedMessages = new System.Collections.Generic.List<PlayerListEvent>();

然后,当你的消息到达时,你可以创建该类的新实例,如果它有效,则将其添加到队列中以便稍后处理(你可以在这里做任何事情,包括触发后台工作进程来处理传入的消息等):

    private static void HandleMessage(BattlEyeMessageEventArgs args) {
    //call a method to analyze data parse
        var oPlayerListEvent = new PlayerListEvent(args.Message);
        if (oPlayerListEvent.MessageIsValid()) {
            lock (m_cReceivedMessages)  {
                m_cReceivedMessages.Add(oPlayerListEvent);
            }
        }
    }

相关内容

  • 没有找到相关文章

最新更新