0

我正在尝试从其 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)

提供市场扫描仪请求产生的数据。

4

2 回答 2

2

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

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

所以基本上要订阅Click按钮的事件,你需要一个接受 anobject和 an的方法EventArgs。所以要订阅它,你这样做:

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、aContractDetails和 4 strings)的方法。所以要订阅它,你这样做:

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

Action代表:

封装具有单个参数且不返回值的方法。

在您的情况下,它是Action具有更多参数的委托。

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

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

你可以阅读这篇文章或使用 lambda 的谷歌事件处理程序,并且有很多文章。

于 2017-02-13T00:34:11.750 回答
0

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

于 2017-02-13T00:08:44.083 回答