2013-09-15 2 views
2

Два потока: основной (GUI) и рабочий. Работник просит обновить основное, используя Dispatcher.Invoke(...). В какой-то момент, в результате вмешательства пользователя, я должен прервать работника, используя Thread1.Abort(). Но тупик, кажется, создается в этой последовательности:Thread.Abort() создает тупик при вызове рабочего потока Dispatcher.Invoke()

  1. T1 вызывает для действия
  2. основного потока прерывается T1

enter image description here

Я знаю, Abort динг является злом (что должен ли я вставлять CheckIfCanceled() каждые две строки?), но при условии, что это необходимо - как я могу предотвратить тупик?

+0

Пункт использования Dispatcher.Invoke() вместо Dispatcher.BeginInvoke() заключается в том, что вы можете использовать его возвращаемое значение. И вы можете выбросить исключение и поймать его в потоке. Это дает вам два отличных способа остановить поток, не прерывая его. –

+0

Вам действительно нужно немедленно прекратить поток? Не можете ли вы просто проверить «IsCancellationRequested» один раз (или несколько раз) в первичном цикле потока? – svick

+0

@ HansPassant, я не понимаю, в чем ваш смысл. Как я могу остановить поток таким образом? У меня длинный рабочий поток, он время от времени запрашивает GUI для вызова, как это может мне помочь? – Tar

ответ

0

В модели потоковой передачи Windows вы не можете прервать поток из-за его контекста выполнения. Вы должны указать рабочий поток, чтобы выйти из его рабочего метода (затем завершить поток), для этого вы можете использовать что-то вроде CancellationToken или другого флага перекрестного потока. Thread.Abort() выдаст исключение, но на самом деле не гарантировано время, чтобы сделать это специально, когда вы используете его с блокирующим многопоточным алгоритмом.

Лучшей альтернативой для вас является вызов с использованием BeginInvoke(), а затем используйте WaitHandle, чтобы дождаться ответа (это приостановит поток, не затрачивая процессорные циклы, ожидающие цикла). Когда основной поток посещает ваш запрос на вызов, он будет сигнализировать через WaitHandle, что поток может возобновиться. Используйте флаг, указывающий на поток, если он должен выйти из возобновления.

Смежные вопросы