Как остановить запланированные обновления пользовательского интерфейса, если я получу новые? - PullRequest
0 голосов
/ 05 июня 2019

Итак, у меня есть окно с изменяемым размером, которое рисует график, рассчитанный для текущих значений, которые он вычисляет. Если я увеличу окно, оно будет перерисовывать и масштабировать все, в том числе, когда график достигает новых значений maxY и maxX, используя их в качестве опорных точек для определения положения других точек. Это работает нормально, но если я изменяю размер окна, и многие вещи запланированы для обновления, это окно изменяет размеры нормально, но график подражает тому, что он должен был делать пару (до 4) секунд назад.

Если я правильно понимаю, каждый раз, когда я вызываю свой поток пользовательского интерфейса, который заблокирован, и даю ему новые координаты для рисования, он заканчивает текущую и затем переходит к следующей. Я понимаю, почему вы этого хотите, но поскольку график более или менее постоянно масштабируется, он в любом случае удаляет себя при каждом обновлении, поэтому я бы сэкономил довольно много вычислительной мощности и времени выполнения, если бы просто завершил каждую текущую задачу и перепрыгнул через все накопленное задание прямо на самое новое, так как сохраненные все равно устарели

Есть ли способ сделать это?

Я думал о 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 голосов
/ 14 июня 2019

Так что я исправил это. Моя архитектура сохраняет все журналы, поэтому мне не нужно сохранять координаты, если мне нужны новые значения, я могу просто, каждый раз, когда мне нужны новые координаты, вычислять их из журналов. Как это:

// 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, чтобы я мог вызвать его снова.

...