- 私は、Windows フォーム アプリケーション (.NET 4.0) に取り組んでいます。
- 私のフォームには、VS2010 に含まれている Microsoft チャート コントロールを使用した「Fast Line」チャートが含まれています。
- グラフは約 20,000 のデータポイントでいっぱいになります。
- 私のアプリケーションは、DDE (Dynamic Data Exchange) を介してリアルタイムでサーバーから市場データの受信を開始し、それをチャートに追加します。
注:私はサーバーを制御できないため、時代遅れのテクノロジであるにもかかわらず、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 に追加し、それ自体を無効化 (更新) するには、一定の時間 (1 秒未満) が必要です。一方、サーバーは多くの場合、データ値を非常に迅速に送信します (たとえば、間に 5 ミリ秒)。だから私は次のことを試しました:
System.Threading.Thread.Sleep(800)
Chart1.Series("Bid").Points.AddY(myPrice)
したがって、アプリケーションを一時停止して、新しいポイントを追加する前にチャートが作業を完了する時間を与えます。アプリケーションは、例外をスローする前に数分間動作するようになりました。(ただし、Sleep() の値を変更しても、それ以上は役に立ちません)
私がオンラインで見つけることができる唯一の助けは、一度に 1 つの新しいデータ値をキャッシュから解放して (チャートの動作が終了するたびに)、受信データをキャッシュ キューに入れる必要があると述べている誰かの古い投稿です。
私の質問は、これをどのように行うかです。
他の提案は大歓迎です!