了解传入消息的事件处理

Understanding event handling for incoming messages

我试图理解他们 API 中 Interactive Brokers 示例中的部分代码。它是关于处理来自传入消息的数据,虽然我了解事件处理的一般流程,但我不了解这一部分:

ibClient.ScannerData += (reqId, rank, contractDetails, distance, benchmark, projection, legsStr) => 
    HandleMessage(new ScannerMessage(reqId, rank, contractDetails, distance, benchmark, projection, legsStr));

这行代码发生了什么? ibClient.ScannerData += ([params]) => f(g([params]))

正在发生

HandleMessage 方法显然负责处理传入的消息,并且由于这行代码只有 运行 一次,我相信这是告诉 ibClient.ScannerData 信息如何处理 ScannerData 发送到 ibClient.

的信息

这就是 ibClient 在后端的样子 -

public event Action<int, int, ContractDetails, string, string, string, string> ScannerData;

void EWrapper.scannerData(int reqId, int rank, ContractDetails contractDetails, string distance, string benchmark, string projection, string legsStr)
{
    var tmp = ScannerData;

    if (tmp != null)
        tmp(reqId, rank, contractDetails, distance, benchmark, projection, legsStr);
}

其中 EWrapper.scannerData 是 -

void  scannerData (int reqId, int rank, ContractDetails contractDetails, string distance, string benchmark, string projection, string legsStr)

provides the data resulting from the market scanner request.

ibClient.ScannerData 是一个事件列表。

这会向列表中添加一个新事件:

ibClient.ScannerData += (reqId, rank, contractDetails, distance, benchmark, projection, legsStr) => 
    HandleMessage(new ScannerMessage(reqId, rank, contractDetails, distance, benchmark, projection, legsStr));

这会获取事件列表,并调用所有已注册的事件:

var tmp = ScannerData;

if (tmp != null)
    tmp(reqId, rank, contractDetails, distance, benchmark, projection, legsStr);

找到一些关于 += 函数操作的解释:+= new EventHandler(Method) vs += Method

这基本上是为事件分配事件处理程序。让我们看一个参数较少的更简单的示例,以帮助澄清混淆。如果你查看 Button class,它有一个点击事件,事件的签名是这样的:

public delegate void EventHandler(object sender, EventArgs e);

所以基本上要订阅按钮的 Click 事件,您需要一个采用 objectEventArgs 的方法。因此,要订阅它,您可以这样做:

button.Click += new EventHandler(Button_Click);

或者这个:

button.Click += (se, ev) => Button_Click(sender, e);

或者更短,你可以这样做:

button.Click += Button_Click;

他们都在做同样的事情。他们说当按钮的 Click 事件被触发时,调用 Button_Click 方法。该方法如下所示:

private void Button_Click(object sender, EventArgs e)
{
    // code here
}

+= 正在为 Click 事件订阅或添加处理程序。您可以添加任意多个。如果要取消订阅或删除处理程序,请使用 -=.

在你的情况下,事件是这样的:

public event Action<int, int, ContractDetails, string, string, string, string> ScannerData;

所以说要订阅ScannerData事件,你需要一个有7个参数的方法(2个ints,一个ContractDetails和4个string秒)。所以要订阅它,您可以这样做:

ibClient.ScannerData += (reqId, rank, contractDetails, distance, benchmark, projection, legsStr) => 
    HandleMessage(new ScannerMessage(reqId, rank, contractDetails, distance, benchmark, projection, legsStr));

Action 代表:

Encapsulates a method that has a single parameter and does not return a value.

在您的例子中,它是一个具有更多参数的 Action 委托。

这个=>是一个lambda符号。本质上它可能是这样的:

this.ScannerData += new Action<int, int, ContractDetails, string, string, string, string>(
    HandleMessage
    (new ScannerMessage(reqId, rank, contractDetails, distance, 
                        benchmark, projection, legsStr));

您可以阅读 this 文章或 google event hanlders with lambda 并且有很多文章。