C# 线程和垃圾收集

C# 线程和垃圾收集,c#,multithreading,garbage-collection,weak-references,C#,Multithreading,Garbage Collection,Weak References,我有一个持续运行的windows服务,它创建一些线程来完成一些工作。我想确保这些线程被正确地处理(在它们完成后被垃圾收集) 但是,我也希望能够定期检查它们是否处于活动状态,如果它们处于活动状态,则终止它们。不过,我知道我不能保留对它们的任何引用,因为这样它们就不会被垃圾收集 有没有其他方法可以检查用户定义线程的存在/状态?我在想,使用WeakReference,可能会出现如下情况:(我现在无法完全测试,或者我只需要自己测试) 但我不确定WeakReference到底是如何工作的。有没有关于如何正

我有一个持续运行的windows服务,它创建一些线程来完成一些工作。我想确保这些线程被正确地处理(在它们完成后被垃圾收集)

但是,我也希望能够定期检查它们是否处于活动状态,如果它们处于活动状态,则终止它们。不过,我知道我不能保留对它们的任何引用,因为这样它们就不会被垃圾收集

有没有其他方法可以检查用户定义线程的存在/状态?我在想,使用
WeakReference
,可能会出现如下情况:(我现在无法完全测试,或者我只需要自己测试)


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

使用线程池。不要自己生成线程,也不要发明轮子。

使用线程池。不要自己生成线程,也不要发明轮子。

myThread是一个方法变量吗?或者

在大多数情况下,只要有可能,线程只会被垃圾收集。如果
myThread
是一个方法变量,则无需将
myThread
设置为
null
,因为此时不存在该变量

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

关于终止/中止一个线程……<强>永远> /强>一个好主意;你不知道线程在那一点上做了什么。之后,你的整个进程就注定要失败了。如果可能的话,考虑让这个工作者检查一个“中止”。如果不可能的话,考虑在单独的进程中完成这项工作。一个进程甚至比线程更昂贵,但是它的优点是它是孤立的;你可以在不影响你自己的情况下杀死它。当然,你仍然可以破坏它正在工作的任何文件等等。


P.>坦白地说,我考虑中止一个线程的主要时间是,如果我的进程已经死了,我试图尽快把它排除在外。

< P>是<代码> MyType < /代码>一个方法变量?还是……?/P> 在大多数情况下,只要有可能,线程只会被垃圾收集。如果
myThread
是一个方法变量,则无需将
myThread
设置为
null
,因为此时不存在该变量

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

关于终止/中止一个线程……<强>永远> /强>一个好主意;你不知道线程在那一点上做了什么。之后,你的整个进程就注定要失败了。如果可能的话,考虑让这个工作者检查一个“中止”。如果不可能的话,考虑在单独的进程中完成这项工作。一个进程甚至比线程更昂贵,但是它的优点是它是孤立的;你可以在不影响你自己的情况下杀死它。当然,你仍然可以破坏它正在工作的任何文件等等。


P.>坦白地说,我会考虑中止一个线程的主要时间是如果我的进程已经濒临死亡,我试图尽快摆脱痛苦。

确保线程被清理的最简单的方法仅仅是确保他们的工作最终终止(成功或其他)。。我很好奇在什么情况下会产生一个线程,而你希望在它完成工作之前将其清理干净。无论如何,中止线程是一个非常糟糕的主意。这通常会起作用,但你在这里内置了一个定时炸弹。确保线程被清理干净的最简单方法就是确保它们的工作最终停止取消(成功或以其他方式)。我很好奇在什么情况下可能会产生线程,并且您希望在它完成工作之前将其清理干净。无论如何,中止线程是一个非常糟糕的主意。这通常会起作用,但您在这里内置了一个定时炸弹。要对Marc的答案添加更多内容,您可以查看该类。它支持取消(如果我在.NET 3.5中是正确的)和进度报告(如果我在.NET 4.5中是正确的)。@oleksii的确,但取消并不等同于任意中止;要使取消正常工作,代码本身需要可取消要在Marc的答案中添加多一点内容,您可以看到该类。它支持取消(如果我在.NET 3.5中是正确的)和进度报告(如果我在.NET 4.5中是正确的)。@oleksii确实如此,但取消并不等同于任意中止;要使取消正常工作,代码本身需要是可取消的,但我希望我的轮子有四个面!但我希望我的轮子有四个面!
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
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();
    {
}