Как отменить асинхронный вызов?

Я высоко поощрил бы читать мнение Eric Sink о вопросе:

Глава 7: Ответвления

я, как Eric, предпочитаю стиль "папки", переходящий это, он говорит о.

18
задан Kate Gregory 14 December 2012 в 16:19
поделиться

3 ответа

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

В случае BeginInvoke это сложно с чем-либо сделать. но глобальный флаг, потому что работа выполняется в пуле потоков, и вы не знаете, какой поток. У вас есть несколько вариантов (в порядке предпочтения):

  1. Используйте BackgroundWorker вместо BeginInvoke . Он имеет встроенную функцию отмены . Это имеет и другие преимущества, такие как мониторинг прогресса и обратные вызовы «Работа завершена» . Он также прекрасно обрабатывает исключения .
  2. Используйте ThreadPool. QueueUserWorkItem , передавая объект в качестве состояния, которое имеет метод Cancel () , который устанавливает флаг Отменено , который исполняющий код может проверить. Конечно, вам необходимо сохранить ссылку на объект состояния, чтобы вы могли вызвать для него Cancel () (что и делает за вас BackgroundWorker - у вас есть компонент на вашу форму. (Спасибо Фредрику за напоминание об этом).
  3. Создайте свой собственный делегат ThreadStart , передав объект состояния, как в варианте 2.
18
ответ дан 30 November 2019 в 09:03
поделиться

Если вы ищете метод TerminateAsnyc, вы его не найдете. Поэтому нет, вероятно, не существует элегантного способа использования Control.BeginInvoke / EndInvoke. Таким образом, я бы поставил логический флаг в поток пользовательского интерфейса, и делегат, выполняемый асинхронно, периодически проверял этот флаг во время его выполнения.

Однако вы можете проверить использование фоновых рабочих потоков.

1
ответ дан 30 November 2019 в 09:03
поделиться

Определенно есть и другие решения, хотя я не знаю, можно ли назвать их "элегантными".

вы можете вызвать Abort или Interrupt в потоке, но это может иметь некоторые отрицательные побочные эффекты. Лично для этого я предпочитаю по возможности использовать BackgroundWorker. У него есть функция отмены, но она похожа на то, что вы упомянули, - флаг bool в классе, который вы должны периодически проверять в исполняемом коде (по крайней мере, это не глобальный флаг). Эта статья об остановке потоков в .NET немного устарела, но в ней рассматриваются некоторые подводные камни других опций, о которых я упоминал выше.

0
ответ дан 30 November 2019 в 09:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: