Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是否应该始终在C#中保留对正在运行的线程对象的引用?_C#_Multithreading_Reference - Fatal编程技术网

是否应该始终在C#中保留对正在运行的线程对象的引用?

是否应该始终在C#中保留对正在运行的线程对象的引用?,c#,multithreading,reference,C#,Multithreading,Reference,还是可以这样做: new Thread( new ThreadStart( delegate { DoSomething(); } ) ).Start(); ? 我似乎记得在这种情况下,Thread对象将被垃圾收集,但底层OS线程将继续运行,直到委托的末尾传入它为止。我基本上是在寻找线程池功能,但不希望线程成为后台线程(即,我希望它们保持应用程序的活动状态) 更新: 根据Jason的说法,CLR在运行时实际上保留了对Thread对象的内部引用,因此在线程退出之前不会对其进行垃圾收集。这取决于具

还是可以这样做:

new Thread( new ThreadStart( delegate { DoSomething(); } ) ).Start();
?

我似乎记得在这种情况下,Thread对象将被垃圾收集,但底层OS线程将继续运行,直到委托的末尾传入它为止。我基本上是在寻找线程池功能,但不希望线程成为后台线程(即,我希望它们保持应用程序的活动状态)

更新:

根据Jason的说法,CLR在运行时实际上保留了对Thread对象的内部引用,因此在线程退出之前不会对其进行垃圾收集。

这取决于具体情况。在用户可以取消线程操作的情况下,您应该保留引用,以便在用户需要时取消线程。在其他情况下,可能不需要存储引用。

最好问一个问题“这个线程多久可以启动一次?”是每个应用程序、每个类、每个对象实例还是每个方法调用?这可能会告诉您要将其存储在哪种类型的变量(如果有的话)。

我通常发现,如果我需要像您在示例中那样直接启动一个新线程,而不是从线程池中获取一个线程,那么它是一个长时间运行的线程,我以后需要对它的引用来终止它,监视它,对于短期运行的线程,如在后台线程上调用IO等,我总是使用线程池线程(通常通过someDelete.BeginBlah(…)方法调用间接实现)。当使用像这样的线程池线程时,我不希望保留引用。我不知道其他程序员是否会不恰当地引用该线程。如果我不需要引用,我就不会把它放在任何地方,把代码弄得乱七八糟


编辑:要回答您关于正在进行垃圾收集的线程的编辑,在线程运行时不会发生这种情况。CLR保留对每个正在运行的线程的引用。表示线程的对象将不会被收集。

是的,您应该这样做,因为您永远不知道以后何时必须更改代码才能以某种方式处理线程。那样,把太多的东西放在一行上太难看了


所以说实话,你可以按自己的方式来做,所以答案真的可以归结为代码风格偏好。

除了上面“m3rLinEz”发布的内容,另一个缺点是,如果线程中发生任何异常,甚至很难检测到这种情况。

我在生产代码中遇到过许多这样做是合适的情况。所以,是的,在一行中定义并开始一个线程,而不保留引用,这是有意义的。我认为保留一个“以防万一”的参考资料是在违背创建最简单的工作原理

对于第二部分,不,它在运行时不会被GC'd;线程是根级别的对象,GCtor将从中追踪引用。只有当任何正在运行的线程(包括您在其上启动的线程)不再能够访问该线程实例时,该线程实例才会是GCd


还要注意那些已经创建但从未启动的线程实例。我相信它们会永远存在。

取消是没有必要的——这是一个后台(同步)操作,但我希望它能在关机时保持应用程序的活动状态,这样它就可以在退出前执行最后一次同步。我一直在使用线程池,直到我意识到退出应用程序会中止线程。基本上,我会每5分钟执行一次该行,并且担心它是否会泄漏,或者线程是否会正常运行。线程是否会泄漏(或者更糟的是,简单地循环到无穷大)取决于它正在执行的代码。派生anon线程是否合适取决于它将运行的代码。啊,很酷,在这种特殊情况下这并不重要,但它可能会在退出后被收集,对吗?是的。对线程对象的引用与实际执行线程一起放置在堆栈上。一旦实际线程完成,那么如果我正确地调用了Richter,就不会有对thread对象的引用。简而言之,我是通过C#或C#在CLR中读到的。这两本书都很棒。思考这个问题的一种方式是,“如果对象不存在,孤立线程中的执行逻辑如何调用System.Threading.thread.CurrentThread?”Jason,你假设有人会首先考虑尝试一下,来测试这个。。。我是说我当然会的。。嘿。。。嗯=(