- Я работаю над приложением Windows Forms (.NET 4.0).
- Моя форма содержит диаграмму «Быстрая линия» с использованием элемента управления диаграммы 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
Вы получите идею.
ПРОБЛЕМА:
Это отлично работает в течение нескольких секунд, пока не произойдет сбой диаграммы, выдав исключение: «Сбор был изменен; операция перечисления может не выполняться».
Iя потратил много времени на изучение причин, которые могут быть причиной этого в моем конкретном случае, и я пришел к выводу, что причина в том, что диаграмма получает данные быстрее, чем она может обработать.Он уже загружен большим количеством данных и требует определенного времени (менее секунды) для добавления полученных данных в новую DataPoint и аннулирования (обновления) самого себя.В то время как сервер часто отправляет значения данных очень быстро (например, 5 мс между).Итак, я попробовал следующее:
System.Threading.Thread.Sleep(800)
Chart1.Series("Bid").Points.AddY(myPrice)
, тем самым приостановив приложение, чтобы дать графику время для завершения своей работы перед добавлением новой точки, и угадайте, что?Приложение теперь работает в течение нескольких минут, прежде чем выдать исключение.(однако изменение значения в Sleep () больше не помогает)
Единственная помощь, которую я могу найти в Интернете, - это старая публикация, в которой упоминается, что вы должны поместить входящие данные в очередь кэша с одной новойзначение данных, высвобождаемое из наличных за один раз (каждый раз, когда график заканчивает работать).
Мой вопрос: как бы вы это сделали?
Приветствуются другие предложения!