2017-08-26 66 views
2

我使用的WebSockets動用我的畫布上的數據性能問題:Dispatcher.Invoke更新WPF畫布造成

webSocket.OnMessage += (sender, e) => 
{ 
    String websocketData = e.Data.Substring(3); 
    WebSocketDataStructure jsonData = JsonConvert.DeserializeObject<WebSocketDataStructure>(websocketData); 

    // Give control back to main thread for drawing 
    Application.Current.Dispatcher.BeginInvoke(
     DispatcherPriority.Background, 
     new Action(() => this.updateCanvas(jsonData))); 
    }; 

private void updateCanvas(WebSocketDataStructure myData) 
{ 
    CanvasUtils.DrawLine(MyCanvas, colorNormalBrush, myData.hsLine.x1, myData.hsLine.y1, myData.hsLine.x2, myData.hsLine.y2); 
} 

當我得到每秒的多封郵件應用程序啓動滯後。我讀過使用Dispatcher.BeginInvoke()對於處理頻繁的數據不好,因爲我們每次都立即切換回UI-Thread。

有沒有更好的實現方法?我想過創建一個計時器並每隔一整秒更新一次UI線程。這可以通過將websocket數據存儲在列表中,並在UI線程(https://en.wikipedia.org/wiki/Producer%E2%80%93consumer_problem)上處理它。這種方法唯一的問題是,我無法在UI線程上使用Thread.Sleep(1000)設置無限循環。

回答

1

你可以排隊的高頻繁的數據,並以較低的速度讀取數據隊列項目。通過使用DispatcherTimer,您可以避免直接調用Dispatcher。

var queue = new ConcurrentQueue<WebSocketDataStructure>(); 

webSocket.OnMessage += (s, e) => 
{ 
    var websocketData = e.Data.Substring(3); 
    var jsonData = JsonConvert.DeserializeObject<WebSocketDataStructure>(websocketData); 

    queue.Enqueue(jsonData); 
}; 

var timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) }; 

timer.Tick += (s, e) => 
{ 
    WebSocketDataStructure data; 

    while (queue.TryDequeue(out data)) 
    { 
     CanvasUtils.DrawLine(MyCanvas, colorNormalBrush, 
      data.hsLine.x1, data.hsLine.y1, data.hsLine.x2, data.hsLine.y2); 
    } 
}; 

timer.Start(); 
+0

這正是我想要的。謝謝! – Beric