我正在使用外部类来打开与远程应用程序的连接。此类接收来自远程应用程序的数据,该数据通过处理程序处理。
对于这个处理程序,我添加了几个检查来分析单独的方法中的数据。但是我现在停留在需要再次访问对象的位置,触发事件以调用它上面的方法。我确信这是一个非常基本的问题,但我只是从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
}
答案 0 :(得分:1)
通常,事件使用在其签名中具有两个参数的委托。用于表示发送方的对象“source”参数和用于表示事件args的“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);
}
答案 1 :(得分: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>();
然后,当您的消息到达时,您可以创建该类的新实例,如果它有效,则将其添加到队列中以便稍后处理(您可以在此处执行任何操作,包括触发后台工作进程来处理传入消息等):
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);
}
}
}
答案 2 :(得分:1)
修改处理程序以传递对象:
b.MessageRecievedEvent += (e) => HandleMessage(b, e);
....
private static void HandleMessage(IBattleNet b, BattleMessageEventArgs args) {
....
lambda表达式将args存储为'e',然后通过传递对象和'e'来调用HandleMessage。
如果您有权访问并可以在IBattleNET内部更改事件本身,那么提出的Pickles会议就是更好的做法。