- 我工作的一個Windows窗體應用程序(.NET 4.0)。
- 我的表單包含使用VS2010中包含的Microsoft圖表控件的「Fast Line」圖表。
- 該圖表充滿大約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中並使其自動失效(刷新)。而服務器通常非常快速地發送數據值(例如中間5ms)。所以我嘗試了以下內容:
System.Threading.Thread.Sleep(800)
Chart1.Series("Bid").Points.AddY(myPrice)
因此暫停應用程序可以給時間圖表添加新點前完成其工作,你猜怎麼着?在拋出異常之前,應用程序現在可以運行數分鐘。 (改變Sleep()中的值並沒有幫助)然而,
我唯一可以在網上找到的幫助是有人提到你應該將傳入的數據放入緩存隊列中,有一個新的數據值一次從現金中釋放(每次圖表完成工作時)。
我的問題是你會怎麼做呢?
歡迎您提出其他建議!
任何機會,從一個非UI線程更新圖表數據採集是嗎? – Gabe 2011-05-10 18:40:19
這聽起來像是一個線程問題 - 有人試圖在枚舉時修改集合。 – rsbarro 2011-05-10 18:47:17
OnAdvise是一個事件委託功能嗎?嘗試調用方法AddY而不是執行。 (或者更好的辦法是查看InvokeRequired的值,假設這個值是真的,我認爲這是真的,如果沒有調用它(同步地將數據傳遞給另一個線程),你不能安全地調用它。但是,需要做的事情是將結果中的附加點保留下來,並在停止迭代數據點之後添加它們。在迭代過程中,集合不會被改變,而下一個傳遞將會有更新的數據。 – 2011-05-10 18:48:01