Как отменить или завершить рабочий процесс изнутри самого себя


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

Я запускаю свои рабочие процессы с помощью фабрики. Фабрика создает вспомогательный класс (wfManager), и вспомогательный класс запускает фактический рабочий процесс с помощью WorkflowApplication.

Рабочий процесс сам определяет, является ли он следует закрыть на основании того, если файл пропал без вести. Рабочий процесс имеет ссылку на wfManager, который его запустил, поэтому он называется workflowApplication.закрыть от wfManager

Я думал, что если я использую WorkflowApplication.закройте от wfManager, что рабочий процесс будет закрыт.

Однако время закрытия истекло.

Что может привести к тайм-ауту Close to и есть ли универсальный способ закрыть или завершить рабочий процесс с помощью кода?

3 2

3 ответа:

У вас есть в основном 3 варианта завершения рабочего потока:

  • Cancel
    Как вы видели, это подождет немного времени (чтобы рабочий процесс мог закончить все, что он в данный момент делает), затем закроет рабочий процесс, а затем вызовет обработчик OnCompleted
  • Terminate
    Это требует причины для завершения (как param), ждет немного времени (чтобы рабочий процесс мог закончить все, что он в данный момент делает), затем закрывает рабочий процесс, а затем вызывает обработчик OnCompleted
  • Abort
    Этот просто убивает рабочий процесс и не вызывает обработчик OnCompleted.

Ссылки на MSDN:

Кроме того, вы можете завершить рабочий процесс изнутри рабочего процесса, используя действие TerminateWorkflow.

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

Если рабочий процесс решает, что он хочет отменить себя, есть два варианта

  1. Throw an unhandled exception-приводит к прерыванию рабочего процесса (подходит для возобновления)
  2. Используйте действие завершить-результаты в завершенном рабочем процессе (workflow completes)

В вашем сценарии вы должны использовать действие завершить.

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