Вопрос

Я недавно пытался использовать backgroundworker вместо " classic " я понимаю, что это вызывает, по крайней мере для меня, больше проблем, чем решений. У меня есть фоновый работник, который выполняет синхронное чтение (в данном случае из serialPort) и блокируется около 30 секунд в одной строке кода, тогда отмена отмены не является решением. Я вижу, что если приложение закрывается в этот момент (либо с помощью кросс-кнопки и Application.Exit ()), процесс навсегда удерживает зомби.

Мне нужен способ принудительно прервать или убить поток фонового работника.

Это было полезно?

Решение

Я не совсем уверен в том, чего вы пытаетесь достичь, но, возможно, Событие SerialPort.DataReceived - лучшее решение?

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

Кроме того, мне не нравится идея прерывания потока. Это кажется опасным, и многопоточным приложениям больше не нужно рисковать.

Другие советы

Я собрал один, который (я думаю) делает работу. Пожалуйста, дайте мне знать, если я уйду. Вот простой пример того, как это работает.

var backgroundWorker = new BackgroundWorker(){WorkerSupportsCancellation = true};

backgroundWorker.DoWork += (sender, args) =>
         {                 
                 var thisWorker = sender as BackgroundWorker;
                 var _child = new Thread(() =>
                                               {
                                                   //..Do Some Code

                                               });
                 _child .Start();
                 while (_child.IsAlive)
                 {
                     if (thisWorker.CancellationPending)
                     {
                         _child.Abort();
                         args.Cancel = true;
                     }
                     Thread.SpinWait(1);
                 }                 
         };

 backgroundWorker.RunWorkerAsync(parameter);
 //..Do Something...
backgroundWorker.CancelAsync();

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

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

Процесс не должен превращаться в зомби, поскольку поток BackgroundWorker помечен как " background " и должен заканчиваться, когда пользовательский интерфейс закрыт.

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

Вы можете попробовать это:

            backgroundworker.Dispose();
            backgroundworker = null;
            GC.Collect(); //this helps cleans up ram
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top