我认为这个问题需要了解 API 附带的 Interactive Broker 的 C# 示例应用程序是如何工作的。我正在尝试修改 IB 随 API 提供的示例 C# 应用程序以请求多个历史数据系列,但我遇到了多个问题。看来我需要让程序等到当前数据请求完成后再提交第二个、第三个......等等等等。如果我添加以下代码(假设我添加了一个按钮来启动该过程),则第二个请求似乎“超过”了第一个请求,弄乱了每个系列在应用程序中生成的图表。即数据合并到一张图表中。过多的请求也会导致 IB 开始拒绝数据请求的竞争条件。这种情况下的代码是:
private void button7_Click(object sender, EventArgs e)
{
if (IsConnected)
{
srInputTickerFile = new StreamReader(stInputTickerFileName);
if (!inputTickerFileOpenFlag)
{
srInputTickerFile = new StreamReader(stInputTickerFileName);
inputTickerFileOpenFlag = true;
}
while (srInputTickerFile.Peek() >= 0)
{
String line = srInputTickerFile.ReadLine();
String[] lineSplit = line.Split(',');
string ticker = lineSplit[0];
string timeDateTo = lineSplit[1];
string myDuration = lineSplit[2];
string myBarSize = lineSplit[3];
string myWhatToShow = lineSplit[4];
int myRTH = Int32.Parse(lineSplit[5]);
Contract contract = GetMDContractForHistorical(line);
contract.ConId = histCounter + 1;
string endTime = hdRequest_EndTime.Text.Trim();
string duration = hdRequest_Duration.Text.Trim() + " " + hdRequest_TimeUnit.Text.Trim();
string barSize = hdRequest_BarSize.Text.Trim();
string whatToShow = hdRequest_WhatToShow.Text.Trim();
int outsideRTH = contractMDRTH.Checked ? 1 : 0;
historicalDataManager.AddRequest(contract, timeDateTo, myDuration,
myBarSize, myWhatToShow, myRTH, 1, cbKeepUpToDate.Checked);
historicalDataTab.Text = Utils.ContractToString(contract) + " (HD)";
ShowTab(marketData_MDT, historicalDataTab);
}
srInputTickerFile.Close();
}
}
我尝试过其他的东西,比如在函数调用之后添加
historicalDataManager.AddRequest
以下代码,以便它可以处理请求。
System.Threading.Thread.Sleep(3000);
这里的问题似乎是应用程序将控制权交还给 UI 线程来处理图形,从而阻止了图表的显示。
如果我尝试使用后台工作线程,并将代码的“while”部分放入其中。也就是说,
new Thread(() =>
{
Thread.CurrentThread.IsBackground = true;
//while code above goes here
}).Start();
此代码在 historicalDataManager.AddRequest 处出错,因为它位于 UI 线程,而不是工作线程。如果我在 while 循环中添加代码以更新应用程序中的文本框,它也会生成错误,因为它们驻留在 UI 线程上。
所以我想它归结为 1) 如何正确地限制数据请求 2) 如果使用后台工作线程,如何在 IB 应用程序的 UI 线程上访问函数调用。