У меня запущен цикл, который будет обрабатывать 1000 записей, в настоящее время, когда цикл запущен, его нельзя остановить, и пользователь должен дождаться его завершения. Как я могу остановить цикл, когда кто-то нажимает кнопку «Отмена»? Как мне войти в этот другой распорядок?
Спасибо





Вы можете запустить его в отдельном потоке и прервать его. Только помните, что это может привести к плохому состоянию операции.
Вместо этого вы должен создаете флаг выхода, который поток проверяет в точках безопасности. Если он отмечен для выхода, поток остановится, как только это станет для него безопасным.
Также нужно будет проверить их очередь win msg, стиль DoEvents, чтобы получить сообщение Cancel msg.
На обработку одной записи уйдет не более 99% времени, верно? Если это займет много времени, у вас могут возникнуть другие проблемы.
Обрабатывайте задержку с немедленной обратной связью, когда они нажимают «Отмена» и вращают графику, или накачивают индикатор выполнения, или что-то еще, чтобы убить короткое время до фактической отмены. «Восприятие» немедленного ответа обычно бывает достаточно хорошим!
+1 а может стоит поменять местами порядок двух вариантов? Риск создания плохого состояния из-за прерывания потока для меня делает его определенно вторым выбором.
@ Дэвид Холл Я согласен. Я перефразировал и выделил второй вариант, чтобы было ясно, что это лучший выбор.
Как сказал Марк, вам нужно реализовать какую-то кооперативную синхронизацию. Люди часто стремятся использовать здесь Thread.Abort ... но это плохая идея.
Есть несколько вопросов, которые касаются этого, например, см .: "Есть ли в C# хороший метод для создания исключения в данном потоке."
Вы можете просто использовать компонент Справочная информация.
Он основан на событиях и очень прост в использовании. Очень подходит для того, что вы описываете.
У него хорошая поддержка сигнализация отмены, а также отчет о прогрессе.
И много примеров кода, которые вы можете найти в Google.
Установите свойство WorkerSupportsОтмена так, чтобы оно было истинным.
backgroundworker1.WorkerSupportsCancellation = true;
Делай это прежде чем ты начнешь рабочий.
Затем в цикле вы можете опросить свойство Отмена:
if (backgroundWorker1.CancellationPending) return;
Просто пример, но вы должны уловить идею.
Как описано в отдельных ответах, перед вызовом RunWorkerAsynch () необходимо установить для свойства WorkerSupportsCancellation значение true. Ваш рабочий код все еще должен проверять флаг во время цикла.
Вы можете добавить кнопку отмены, которая устанавливает логический флаг
Внутри цикла добавьте «Application.DoEvents» в ключевые моменты, а затем проверьте логический флаг. Если сработал флаг, выполните очистку и выйдите из цикла.
спасибо за ответы. Это backgroundworker, но когда я использую backgroundworker1.cancelAsync();, я получаю исключение:
"This BackgroundWorker states that it doesn't support cancellation. Modify WorkerSupportsCancellation to state that it does support cancellation"
Как мне это изменить? Это унаследованный код, извините!
backgroundwork1.WorkerSupportsCancellation = true; / * делаем это сразу после создания экземпляра backgroundworker1 * /
Установите для свойства WorkerSupportsCancellation на вашем BackgroundWorker значение true :-)
Вы также должны проверить свойство CancellationPending внутри вашего цикла, чтобы узнать, следует ли прерывать обработку. В статье MSDN, на которую ссылается chakrit, есть хороший блок образца кода.
Обновлено: Да, вы меня на несколько секунд там чакрит :)
Мне нравится эта идея, идея флага выхода привлекательна, хотя пользователи могут пожаловаться, если есть какая-то задержка в достижении этого, надеюсь, это не будет таким большим процессом;)