我最近尝试使用backgroundworker而不是“经典”线程,我意识到它至少对我来说比问题解决方案更多。 我有一个后台工作程序运行同步读取(在这种情况下来自serialPort)并在1个代码行中被阻止大约30秒,然后取消支持不是解决方案。我看到如果应用程序此时关闭(使用十字按钮和Application.Exit()),该过程将永远保持僵尸。
我需要一种强制中止或杀死后台工作线程的方法。
答案 0 :(得分:5)
我把一个(我认为)完成工作。如果我等了,请告诉我。 这是一个如何运作的简单例子。
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基本上运行,直到子线程完成或我们发信号通知它终止进程。然后,后台工作线程可以返回读池。通常我会将它包装在一个帮助器类中,并传递我希望后台线程作为参数传入的委托方法并在子线程中运行它。
请有人让我知道,如果我把头撞到墙上但似乎工作正常..但那就是线程的问题不是它......你在不同的时间运行它会得到不同的结果。
答案 1 :(得分:3)
该进程不应该变成僵尸,因为BackgroundWorker线程被标记为“背景”,并且应该在UI关闭时结束。
答案 2 :(得分:2)
我认为BackgroundWorker不支持杀死该线程。必须在执行作业的方法中取消操作。在你的情况下,我认为常规线程将是最好的选择。
答案 3 :(得分:2)
我不太确定你想要完成什么,但也许SerialPort.DataReceived事件是更好的解决方案?
如果您已经精通线程的使用,我没有看到使用BackgroundWorker的重点。它专为那些首先不了解线程的人设计。
此外,我不喜欢中止线程的想法。这感觉很危险,多线程应用程序不再需要冒险。
答案 4 :(得分:0)
你可以试试这个:
backgroundworker.Dispose();
backgroundworker = null;
GC.Collect(); //this helps cleans up ram