Как отменить асинхронный вызов?
Как отменить асинхронный вызов?.NET APM, похоже, не поддерживает эту операцию.
У меня есть следующий цикл в моем коде, который порождает несколько потоков в ThreadPool. Когда я нажимаю кнопку на своем пользовательском интерфейсе, мне бы хотелось, чтобы эти потоки (или асинхронные вызовы) заканчивались.
foreach (var sku in skus)
{
loadSku.BeginInvoke(...
}
Есть ли какое-нибудь элегантное решение, кроме создания глобального флага "Отмена" и наличия асинхронных методов для его поиска?
Ответы
Ответ 1
"Флаг отмены" - это способ сделать это, хотя и не глобальный, обязательно. Неизбежной точкой является то, что вам нужен some способ сообщить в поток, что он должен остановить то, что он делает.
В случае BeginInvoke
это трудно сделать с чем угодно, кроме глобального флага, потому что работа выполняется в threadpool, и вы не знаете, какой поток. У вас есть несколько вариантов (в порядке предпочтения):
- Используйте
BackgroundWorker
вместо BeginInvoke
. У этого есть функция отмены, испеченная. Это имеет другие преимущества, такие как мониторинг прогресса, и "Work complete" обратные вызовы. Он также красиво обрабатывает исключения.
- Используйте
ThreadPool.QueueUserWorkItem
, передавая объект как состояние, которое имеет метод Cancel()
, который устанавливает флаг Cancelled
, который может проверить исполняемый код. Конечно, вам нужно будет сохранить ссылку на объект состояния, чтобы вы могли называть Cancel()
на нем (что для вас означает BackgroundWorker
) - у вас есть компонент в вашей форме. (Благодаря Fredrik для напоминания об этом).
- Создайте свой собственный делегат
ThreadStart
, передав объект состояния как с параметром 2.
Ответ 2
Если вы ищете метод TerminateAsnyc, вы его не найдете. Поэтому нет, возможно, нет элегантного способа при использовании Control.BeginInvoke/EndInvoke. Таким образом, я поместил бы логический флаг в поток пользовательского интерфейса и выполнил бы делегат асинхронно проверять этот флаг периодически во время его выполнения.
Однако вы можете проверить использование потоков рабочего потока.
Ответ 3
Есть определенные решения, хотя я не знаю, что я бы назвал их "элегантными".
вы могли бы вызвать прерывание или прерывание в потоке, но они могут иметь некоторые отрицательные побочные эффекты. Лично для чего-то подобного я предпочитаю использовать BackgroundWorker, если это возможно. У этого есть функция Отмена, но она похожа на то, что вы упомянули, - флаг bool в классе, который вы должны периодически проверять в исполняемом коде (по крайней мере, это не глобальный флаг). Это сообщение о прекращении потоков в .NET немного устарело, но просматривает некоторые из ошибок других вариантов, о которых я упоминал выше.