- 我正在开发一个 Windows 窗体应用程序(.NET 4.0)。
- 我的表单包含使用 VS2010 中包含的 Microsoft 图表控件的“快速线”图表。
- 该图表填充了大约 20,000 个数据点。
- 然后我的应用程序开始通过 DDE(动态数据交换)从服务器实时接收市场数据并将其添加到图表中。
注意:我无法控制服务器,因此我只能处理 DDE,即使它是一种过时的技术。VS 不再支持 DDE,所以我使用Ndde库,它就像一个魅力。
首先我们连接到服务器,创建一个通知循环,然后订阅 OnAdvise 事件以接收新数据的通知:
Dim client As DdeClient = New DdeClient("ServerApplication", "Bid")
Private Sub StartDDE()
client.Connect()
client.StartAdvise("EURUSD", 1, True, 60000)
AddHandler client.Advise, AddressOf OnAdvise
End Sub
现在我们可以将更新图表的命令放入事件中:
Private Sub OnAdvise(ByVal sender As Object, ByVal args As DdeAdviseEventArgs)
Dim myPrice As Double = args.Text
Chart1.Series("Bid").Points.AddY(myPrice)
End Sub
你明白了。
问题:
这可以正常工作几秒钟,直到图表崩溃并抛出异常:“集合已修改;枚举操作可能无法执行。”
我花了很多时间研究在我的特定情况下可能是什么原因,我得出的结论是,这是因为图表接收数据的速度超过了它可以处理的速度。它已经加载了大量数据,需要一定的时间(不到一秒)将接收到的数据添加到新的 DataPoint 中并使其自身失效(刷新)。而服务器通常会非常快速地发送数据值(例如之间的 5 毫秒)。所以我尝试了以下方法:
System.Threading.Thread.Sleep(800)
Chart1.Series("Bid").Points.AddY(myPrice)
因此暂停应用程序,让图表有时间在添加新点之前完成其工作,你猜怎么着?该应用程序现在可以在引发异常之前运行几分钟。(但是,更改 Sleep() 中的值并没有帮助)
我能在网上找到的唯一帮助是一篇旧帖子,有人提到您应该将传入数据放在缓存队列中,一次从现金中释放一个新数据值(每次图表完成工作时)。
我的问题是你会怎么做?
欢迎其他建议!