我最近尝试使用 backgroundworker 而不是“经典”线程,我意识到至少对我而言,它导致的问题多于解决方案。我有一个后台工作程序运行同步读取(在这种情况下从 serialPort)并在 1 个代码行中被阻塞大约 30 秒,然后取消挂起不是解决方案。我看到,如果此时应用程序关闭(使用十字按钮和 Application.Exit()),该进程将永远保持僵尸状态。
我需要一种强制中止或终止后台工作线程的方法。
我最近尝试使用 backgroundworker 而不是“经典”线程,我意识到至少对我而言,它导致的问题多于解决方案。我有一个后台工作程序运行同步读取(在这种情况下从 serialPort)并在 1 个代码行中被阻塞大约 30 秒,然后取消挂起不是解决方案。我看到,如果此时应用程序关闭(使用十字按钮和 Application.Exit()),该进程将永远保持僵尸状态。
我需要一种强制中止或终止后台工作线程的方法。
我把一个(我认为)放在一起可以完成这项工作。请让我知道我是否离开了。这是一个简单的例子,说明它是如何工作的。
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 线程被标记为“后台”并且应该在 UI 关闭时结束。
我不认为 BackgroundWorker 支持杀死线程。取消操作必须在执行该作业的方法中完成。在您的情况下,我认为常规线程将是最佳选择。
我不太确定您要完成什么,但也许SerialPort.DataReceived事件是更好的解决方案?
如果您已经精通线程的使用,我看不出使用 BackgroundWorker 有什么意义。它是为那些一开始就不懂线程的人设计的。
此外,我不喜欢中止线程的想法。感觉很危险,多线程应用程序不需要再冒险了。
你可以试试这个:
backgroundworker.Dispose();
backgroundworker = null;
GC.Collect(); //this helps cleans up ram