如果有新的UI更新,如何停止计划的UI更新?

时间:2019-06-05 15:17:47

标签: c# wpf multithreading user-interface drawing

因此,我有一个可调整大小的窗口,该窗口根据其计算的实时值绘制了一个图形。如果我增大窗口,则它会重新绘制并缩放所有内容,并且当图形达到新的maxY和maxX时,也会使用它们作为参考点来确定其他点的位置。效果很好,但是如果我调整窗口的大小,并且安排了许多更新的事情,那么窗口的大小也会很好,但是Graph模仿了几秒钟之前(最多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),但是由于我希望有另一种方法,所以我想问一下这里的其他人是否也有类似的问题。

1 个答案:

答案 0 :(得分:0)

所以我修复了它。我的体系结构会保存所有日志,因此不需要保存坐标,如果我需要新的值,则只需在每次需要新的坐标时都可以从日志中计算出来。像这样:

// 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,因此可以再次调用它。