Создание схемы отмены

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

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

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

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

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

РЕДАКТИРОВАТЬ: Вот идея, вдохновленная ответом Джона Сондерса.

Что если в моем потоке обработки запустится фоновый поток, который ожидает изменения Cancel Singleton, а затем сгенерирует исключение из этого процесса? Это похоже на хорошую практику? Это не работает как задумано

РЕДАКТИРОВАТЬ 2: Ответ Джона Сондерса, кажется, лучший на данный момент. Я просто брошу свое собственное исключение, когда пока что синглтон верен. Я буду ждать, чтобы увидеть, если какие-либо другие решения предлагаются

4 ответа

Решение

Thread.Abort - плохая идея, так как он прерывает поток в произвольной точке - вероятно, прерывает его там, где вы меньше всего хотите, чтобы его прерывали.

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

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

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

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

Вместо этого вы можете использовать простой, потокобезопасный логический флаг в качестве статического члена класса, доступного из любого потока, или использовать объект синхронизации, такой как именованный Mutex. Сигнализация объекта синхронизации позволит потоку знать, что он должен отменить.

Похоже, вы используете класс.NET backgroundworker. Я думаю, что вы можете передать параметр объекта в метод RunWorkerAsync, который затем станет доступен фоновому потоку в аргументе обработчика события DoWork.

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

Вы могли бы использовать Thread.Abort() функция в фоновом рабочем потоке. Это кидает ThreadAbortException который вы можете поймать любым из ваших методов, но который будет автоматически переброшен в конце catch блоки.

Также все finally-блоки будут выполнены.

Другие вопросы по тегам