如果我收到新的更新,如何停止计划的 UI 更新?
How do I stop scheduled UI updates if I get new ones?
所以,我有一个可调整大小的 window,它根据它计算的实时值绘制图表。如果我使 window 变大,它会重新绘制和缩放所有内容,当图形达到新的 maxY 和 maxX 时,也会使用它们作为参考点来确定其他点的位置。这工作正常,但如果我调整 window 的大小,并且很多事情都被安排更新,它 window 调整大小很好,但图表模仿了它应该做的一些(向上到 4) 秒前。
如果我理解正确的话,每次我调用我的 UI 线程,它被阻塞,并给他新的坐标来绘制,它完成当前的一个,然后继续下一个。我明白你为什么想要那个,但是由于图形或多或少地不断缩放,无论如何它都会在每次更新时删除自己,所以我会节省相当多的处理能力和运行时间,如果我只完成每个当前任务并跳过所有累积的任务权到最新的,因为存储的任务已经过时了
有办法吗?
我想到了 3 种可能有效的方法,其中第三种是唯一一种,我知道它会起作用,或者更确切地说,是可能的,即使速度很慢:
// (1) If there is a way to check if the UI thread is busy, I could just not send
// a new request to draw another line
if(!uithread.busy)
{
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background,
new Action(() => this.DrawGraph(new List<List<Coordinates>> { CoordinateListA, CoordinateListB })));
}
// (2) As soon as UI thread finishes the current task, it jumps to the newest one
// (3) In my opinion the ugliest solution, I check how long the last drawing took and
// don't send any draw-requests in that time. I will just wait that certain time and
// just then send him the newest results to draw and measure how long that took
如果没有更好的解决方案,我想我会选择(3),但因为我希望有另一种方法,所以我想问问这里是否有其他人有类似的问题。
所以我修复了它。我的架构保存了所有日志,所以我不需要保存坐标,如果我需要新值,每次我需要新坐标时,我都可以从日志中计算它们。像这样:
// beginning of the class
private bool _isDrawing = false;
if (!_graphIsDrawing)
{
_graphIsDrawing = true;
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background,
new Action(() => this.DrawGraph(new List<List<Coordinates>> { CoordinateListA, CoordinateListB }, scalingFactors, canvasSize)));
//I need to invoke, since I am working with multiple threads here. Else it
//would be enough to just call 'this.DrawGraph(...)'
}
///////////
public void DrawGraph(List<List<Coordinates>> listOfGraphs, float[] scalingFactor, int[] canvasSize)
{
lock (_graphDrawLock)
{
this._AlgorithmRuntimeViewA.DrawGraph(listOfGraphs[0], scalingFactor, canvasSize);
this._AlgorithmRuntimeViewB.DrawGraph(listOfGraphs[1], scalingFactor, canvasSize);
_graphIsDrawing = false;
}
}
在这里我再次锁定它,所以不会两个线程同时绘制破坏一切。最后,我再次将 _graphIsDrawing 设置为 false,以便再次调用它。
所以,我有一个可调整大小的 window,它根据它计算的实时值绘制图表。如果我使 window 变大,它会重新绘制和缩放所有内容,当图形达到新的 maxY 和 maxX 时,也会使用它们作为参考点来确定其他点的位置。这工作正常,但如果我调整 window 的大小,并且很多事情都被安排更新,它 window 调整大小很好,但图表模仿了它应该做的一些(向上到 4) 秒前。
如果我理解正确的话,每次我调用我的 UI 线程,它被阻塞,并给他新的坐标来绘制,它完成当前的一个,然后继续下一个。我明白你为什么想要那个,但是由于图形或多或少地不断缩放,无论如何它都会在每次更新时删除自己,所以我会节省相当多的处理能力和运行时间,如果我只完成每个当前任务并跳过所有累积的任务权到最新的,因为存储的任务已经过时了
有办法吗?
我想到了 3 种可能有效的方法,其中第三种是唯一一种,我知道它会起作用,或者更确切地说,是可能的,即使速度很慢:
// (1) If there is a way to check if the UI thread is busy, I could just not send
// a new request to draw another line
if(!uithread.busy)
{
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background,
new Action(() => this.DrawGraph(new List<List<Coordinates>> { CoordinateListA, CoordinateListB })));
}
// (2) As soon as UI thread finishes the current task, it jumps to the newest one
// (3) In my opinion the ugliest solution, I check how long the last drawing took and
// don't send any draw-requests in that time. I will just wait that certain time and
// just then send him the newest results to draw and measure how long that took
如果没有更好的解决方案,我想我会选择(3),但因为我希望有另一种方法,所以我想问问这里是否有其他人有类似的问题。
所以我修复了它。我的架构保存了所有日志,所以我不需要保存坐标,如果我需要新值,每次我需要新坐标时,我都可以从日志中计算它们。像这样:
// beginning of the class
private bool _isDrawing = false;
if (!_graphIsDrawing)
{
_graphIsDrawing = true;
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background,
new Action(() => this.DrawGraph(new List<List<Coordinates>> { CoordinateListA, CoordinateListB }, scalingFactors, canvasSize)));
//I need to invoke, since I am working with multiple threads here. Else it
//would be enough to just call 'this.DrawGraph(...)'
}
///////////
public void DrawGraph(List<List<Coordinates>> listOfGraphs, float[] scalingFactor, int[] canvasSize)
{
lock (_graphDrawLock)
{
this._AlgorithmRuntimeViewA.DrawGraph(listOfGraphs[0], scalingFactor, canvasSize);
this._AlgorithmRuntimeViewB.DrawGraph(listOfGraphs[1], scalingFactor, canvasSize);
_graphIsDrawing = false;
}
}
在这里我再次锁定它,所以不会两个线程同时绘制破坏一切。最后,我再次将 _graphIsDrawing 设置为 false,以便再次调用它。