- Я работаю над приложением Windows Forms (.NET 4.0).
- Моя форма содержит диаграмму Fast Line с использованием элемента управления диаграммой Microsoft, включенного в VS2010.
- Диаграмма заполняется примерно 20 000 точек данных.
- Затем мое приложение начинает получать рыночные данные с сервера через DDE (динамический обмен данными) в режиме реального времени и добавляет их на график.
Примечание. Я не контролирую сервер, поэтому мне приходится иметь дело только с DDE, несмотря на то, что это устаревшая технология. VS больше не поддерживает DDE, поэтому я использую библиотеку Ndde, которая прекрасно работает.
Сначала мы подключаемся к серверу, создаем цикл Advise, а затем подписываемся на событие 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() больше не помогает)
Единственная помощь, которую я смог найти в Интернете, — это старый пост, в котором кто-то упоминал, что вы должны помещать входящие данные в очередь кеша, при этом из кэша высвобождается одно новое значение данных (каждый раз, когда диаграмма завершает работу).
Мой вопрос: как бы вы это сделали?
Другие предложения приветствуются!