Есть ли способ ожидать изменения флага в функции? - PullRequest
0 голосов
/ 26 января 2020

Я попытался сделать простой пошаговый режим для алгоритма, который я запускаю, вот как это выглядит:

    public async Task<bool> AStarAlgorithmAsync(PFSquare curr = null)
    {
        // some algorithm code here
        foreach(var square in Sorroundings)
        {
            if (SteppedMode)
            {
                await Task.Run(Pause);
            }
            if (await AStarAlgorithmAsync(square))
            {
                return true;
            }
        }
    }

В моем приложении у меня есть логическое значение SteppedMode, которое решает, должен ли алгоритм выполнять одну итерацию для каждого события клика. Pause() выглядит следующим образом:

    private void Pause()
    {
        while (!ContinueStep) { }
        ContinueStep = false;
        return;
    }

и в другой части моего (GUI) приложения у меня есть событие, которое устанавливает логическое значение ContinueStep в значение true, которое теоретически должно заканчиваться, пока l oop и продолжить функцию алгоритма. В настоящее время этот фрагмент кода блокирует мой поток GUI, и я почти уверен, что есть лучший способ сделать это.

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

(Это приложение GUI, а не консольное приложение)

1 Ответ

2 голосов
/ 26 января 2020

В качестве метода используется ваше свойство.

Нет смысла устанавливать свойство, чтобы затем немедленно вернуть это свойство в исходное состояние. Как потребитель, я был бы очень смущен таким поведением. Подумайте об этом коде:

var myObj = new MyObject();

myObj.MyBoolean = true;

Console.WriteLine(myObj.MyBoolean); // FALSE!?

Это просто не имеет смысла.

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

public void ContinueStep()
{
    Console.WriteLine("I did some work");
}

Так что вместо этого:

myObj.ContinueStep = true;

вы должны сделать это:

myObject.ContinueStep();

Это не блокирует ваш поток пользовательского интерфейса, а также является более чувственным для вашего потребителя. Метод предполагает, что будет предпринято какое-то действие (которое может или не может привести к изменению состояния объекта - это контекстуальное ожидание).


Бесконечная рекурсия

В стороне; на основе вашего кода AStarAlgorithmAsync - рекурсивная функция, и, казалось бы, бесконечно. Кажется, что нет конечного условия.
Каждый рекурсивный уровень будет взаимодействовать с первым окружением, а затем запускать следующий уровень, который снова будет взаимодействовать с первым окружением, а затем запускать следующий уровень, который снова ...

Это не может быть правдой, но мне непонятно, как это исправить, так как общая картина не объяснена в вашем вопросе


Простая реализация

То, что я пытаюсь сделать, это заставить мою функцию алгоритма выполнить одну итерацию, дождаться щелчка от пользователя и только затем продолжить выполнение алгоритма, есть ли более простой и чистый способ сделать это?

Простой пример такой вещи:

private int _index = 0;

private List<object> _myList = ...; // assume this list contains some elements

public void ProcessNextObject()
{
    if(_index < _myList.Length)
    {
        Process(_myList[_index]);
        _index++;
    }
}

private void Process(object o)
{
    Console.WriteLine("Processing this object!");
}

Затем вы можете подключить событие click для вызова ProcessNextObject().

Обратите внимание, что в этом примере список обрабатывается один раз и не может быть обработан снова. Управляя значением индекса, вы можете изменять это поведение по своему усмотрению.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...