我正在使用外部类打开与远程应用程序的连接。此类从通过处理程序处理的远程应用程序接收数据。
对于这个处理程序,我添加了几个检查来解析不同方法中的数据。但是,我现在停留在需要再次访问该对象的地步,该对象触发了事件以在其上调用方法。我确信这是一个非常基本的问题,但我才刚刚从 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);
}
}
}