Выполнение задач с отмены логика


В мое задание я выполнять длительные NodeJs скрипт из C# с использованием EdgeJs. Поскольку скрипт может занять много времени для выполнения, я хочу, чтобы предоставить пользователю возможность отменить выполнение скрипта в середине. Отмена статус сохраняется в базе данных и функции IsScripteExecutionCancelled возвращает true если пользователь решит отказаться от выполнения.

Для достижения этого я выполнение скрипта в фоновом потоке, используя Task.Run(). Основной поток содержит while цикл, который выполняется до тех пор, пока ScriptExecution или отменен. Я могу решить эту проблему, используя родной System.Threading.Threadно здесь я пытаюсь сделать это с помощью ТПЛ. Вот код, который я поставил на место:

bool executionStarted = false;
bool taskCompleted = false;
Result returnValue;

CancellationTokenSource tokenSource = new CancellationTokenSource();
CancellationToken token = tokenSource.Token;

Task executionTask;
while (!(taskCompleted || token.IsCancellationRequested))
{
    if (!executionStarted)
    {
        executionStarted = true;
        executionTask = Task.Run(() =>
        {
            returnValue = ExecuteScript();
            taskCompleted = true;
        }, token);
    }
    bool taskExecutionCancelled = IsScripteExecutionCancelled();
    if (taskExecutionCancelled)
    {
        tokenSource.Cancel();
    }
}

if(token.IsCancellationRequested)
    returnValue= GetDefaultValueForCancellation();

return returnValue;

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

Вопрос: это правильный путь для решения этой проблемы?



215
1
задан 13 марта 2018 в 10:03 Источник Поделиться
Комментарии
2 ответа


Есть ли лучший способ сделать отмену задач, чем тот, который я реализовал

Нет отмены задач, реализуемых здесь. Путем передачи маркера Task.Run вы просто принять возвращенный задач IsCanceled равного true в случае, если он отменяет себя (без, он получает IsFaulted по OperationCanceledException). Но вам нужно (по крайней мере), чтобы передать маркер DoSomeWorkпотому, что нужно проверить маркер и отменить себя.

Задача отмены работы через сотрудничество будет отменен задач и не имеет ничего общего с Thread.Abort.

0
ответ дан 13 марта 2018 в 03:03 Источник Поделиться

вы создаете здесь переменной и использовать его только один раз


bool taskExecutionCancelled = IsScripteExecutionCancelled();
if (taskExecutionCancelled)
{
tokenSource.Cancel();
}

Я бы просто использовать метод в случае, если заявление, как

if (IsScripteExecutionCancelled())
{
tokenSource.Cancel();
}

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

0
ответ дан 14 марта 2018 в 05:03 Источник Поделиться