线程和垃圾收集

Phi*_*idt 1 c# multithreading garbage-collection weak-references

我有一个连续运行的Windows服务,并创建一些线程来做一些工作.我想确保妥善处理这些线程(完成后收集垃圾).

但是,我也希望能够检查它们是否定期存活并且如果存在则终止它们.我知道我不能保留对它们的任何引用,因为那时它们不会被垃圾收集.

是否有另一种方法来检查用户定义线程的存在/状态?我想的可能是以下使用的东西WeakReference:(我现在无法完全测试,或者我只是自己测试)

List<WeakReference> weakReferences;
Thread myThread = new Thread(() => Foo());
WeakReference wr = new WeakReference(myThread);
weakReferences.Add(wr);  //adds a reference to the thread but still allows it to be garbage collected
myThread.Start();
myThread = null;  //get rid of reference so thread can be garbage collected
Run Code Online (Sandbox Code Playgroud)

然后在我的onTimeElapsed事件开始时(每5分钟运行一次):

foreach(WeakReference wr in weakReferences)
{
    Thread target = wr.Target as Thread;  //not sure if this cast is really possible
    if(target.IsAlive && otherLogic)
    {
         target.Abort();
    {
}
Run Code Online (Sandbox Code Playgroud)

但我不确定WeakReference是如何工作的.关于如何正确地做到这一点的任何想法?

Mar*_*ell 6

是myThread一个方法变量?要么...?

在大多数情况下,线程将尽可能简单地进行垃圾回收.有没有必要设置myThread到null,如果myThread是一个方法的变量,因为这将不存在的时候.

但是,我会注意到线程实际上是非常昂贵的对象(单独的堆栈很难分配).如果可能的话,我建议使用ThreadPool(如果每个项目都是短期的),或者使用定制的工作队列(如果更长),可能有多个工作人员为单个队列服务.

至于终止/中止线程......这绝不是一个好主意; 你不知道线程在那一点上做了什么.在那之后,您的整个过程可能注定失败.如果在所有可能的话,考虑让工人偶尔检查"失败"标志.如果不可能,请考虑在单独的过程中完成工作.一个过程甚至比线程更昂贵,但它具有隔离的优点; 你可以在不影响自己的情况下杀死它.当然,你仍然可以破坏它正在处理的任何文件,等等......

坦率地说,我会考虑中止线程的主要时间是我的进程已经死了,我试图尽快摆脱痛苦.