我正在使用Websockets在画布上绘制数据:
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-Thread。这可以通过将websocket数据存储在List中,并在UI-Thread(https://en.wikipedia.org/wiki/Producer%E2%80%93consumer_problem)上处理它来实现。我唯一的问题是,我无法在UI-Thread上使用Thread.Sleep(1000)建立无限循环。
答案 0 :(得分: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();