Фоновый работник прервать
-
03-07-2019 - |
Вопрос
Я недавно пытался использовать 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