Как отменить задачу, которая не выполняет никаких циклических операторов - PullRequest
0 голосов
/ 27 марта 2012

У меня есть асинхронная задача, которая выполняет функцию. Функция не содержит никаких циклических операторов, но вместо этого она выполняет серию команд SQL на сервере SQL. Теперь у меня есть кнопка в моем окне, которая может отменить эти операции SQL. Другими словами, отмените всю асинхронную задачу.

Я знаю, что для этого метода потребуются CancellationTokenSource и CancellationToken, чтобы отменить задачу, но я видел много примеров в Интернете, и все они показывают, что функция, которую выполняет эта задача, содержит операторы цикла, в которых они проверяют наличие IsCancellationRequested логическое свойство. Но в моем случае это не так. В моей функции нет операторов цикла, в которых я могу проверить это логическое свойство.

, пожалуйста, предложите любой метод / технику.

Любая помощь будет весьма заметна ...

Спасибо заранее ...

Ответы [ 3 ]

1 голос
/ 27 марта 2012

Ну, на самом деле есть только три основных программных потока: последовательность (шаг 1, шаг 2 и т. Д.), Выбор (операторы типа if) и итерация (циклы).

Если вы этого не сделаетеесть какие-либо петли, все, что вам осталось, это выбор и последовательность.Это означает, что ваш код, вероятно, в конечном итоге будет выглядеть примерно так (очевидно, псевдокод):

perform sql (statement1)
if IsCancellationRequested: return

perform sql (statement2)
if IsCancellationRequested: return
:
:
perform sql (statementN)
if IsCancellationRequested: return

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


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

def execSql (sqlStatement):
    perform sql (sqlStatement)
    return IsCancellationRequested

тогда ваши строки станут:

if (perform sql (statement1)): return
if (perform sql (statement2)): return
:
if (perform sql (statementN)): return

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

0 голосов
/ 27 марта 2012

Так сделай их!

Простой пример (Вы можете расширить его, как вам нравится):

List<string> _sqls = new List<string>();
_sqls.Add("Select ... ");
_sqls.Add("Update ... ");
_sqls.Add("Select ... ");

foreach (var sql in _sqls)
{
   Execute(sql);
   if (IsCancellationRequested)
   {
      // Make some rollback
      return;
   }
} 

Для лучшего опыта вы можете использовать List<Func<..>>, List<Action<..>> вместо List<string> или даже придумать шаблоны проектирования Query, Builder, Factory Method.

0 голосов
/ 27 марта 2012

Вы должны проверять это всякий раз, когда вам нужно в вашем коде.Ваш пример (тот, который вы видели) имеет для, поэтому он проверяет отмену на каждой итерации.Поскольку у вас нет для, вам придется вручную выбирать, когда вы хотите проверить, если пользователь отменить его.Поскольку у вас есть запросы, может быть, после каждого запроса или каждые 2 или 3 запроса.Когда вам это нужно.

...