2

我正在使用外部类来打开与远程应用程序的连接。此类接收来自远程应用程序的数据,这些数据通过处理程序进行处理。

在这个处理程序中,我添加了几个检查以在不同的方法中解析数据。但是,我现在被困在我需要再次访问触发事件以在其上调用方法的对象的地步。我确信这是一个非常基本的问题,但我只是从 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
}
4

3 回答 3

1

通常,事件使用在其签名中具有两个参数的委托。一个对象“source”参数表示发送者,一个“args”参数表示事件参数。

如果您有权访问,MessageReceivedEvent则应更改委托以包含“对象”参数来表示发送者。然后您的HandleMessage方法将如下所示:

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

        battleNet.Foo();
        PlayerList(args.Message);
}
于 2012-08-12T00:13:20.193 回答
1

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

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

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

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

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>();

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

    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);
            }
        }
    }
于 2012-08-12T00:13:44.517 回答
1

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

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

lambda 表达式将 args 存储为“e”,然后通过传递对象和“e”来调用 HandleMessage。

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

于 2012-08-12T00:14:32.630 回答