【问题标题】:Should one always keep a reference to a running Thread object in C#?是否应该始终保留对 C# 中正在运行的 Thread 对象的引用?
【发布时间】:2008-12-24 04:34:33
【问题描述】:

或者这样可以吗:

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

?

我似乎记得在这种情况下,线程对象将被垃圾收集,但底层操作系统线程将继续运行,直到传递给它的委托结束。我基本上是在寻找 ThreadPool 功能,但不希望线程成为后台线程(即我希望它们保持应用程序处于活动状态)。

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

【问题讨论】:

  • 一种思考方式,“如果对象不存在,孤立线程中的执行逻辑如何能够调用 System.Threading.Thread.CurrentThread?”
  • Jason,您假设有人会首先考虑尝试进行测试。 ...我的意思是当然会嘿...嘿...呃... =(

标签: c# multithreading reference


【解决方案1】:

我通常发现,如果我需要像您在示例中那样直接启动一个新线程,而不是从线程池中抓取一个,那么它是一个长时间运行的线程,我稍后需要对其进行引用杀死它,监视它等。对于像在后台线程上调用 IO 等短期线程,我总是使用线程池线程(通常通过 someDelete.BeginBlah(...) 方法调用间接地)。当使用这样的线程池线程时,我更喜欢不保留参考。我不知道其他程序员是否会不恰当地使用对该线程的引用。如果我不需要参考,我不会保留它以使代码混乱。

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

【讨论】:

  • 啊酷,在这种特殊情况下并不重要,但大概它会在它退出后被收集,对吧?
  • 是的。对线程对象的引用与实际执行线程一起放置在堆栈上。一旦实际线程完成,如果我正确地回忆起我的 Richter,就不会引用线程对象。我在 CLR 中通过 C# 或简而言之 C# 阅读了它。两本好书。
【解决方案2】:

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

【讨论】:

  • 取消不是必需的——这是一个后台(同步)操作,但我希望它在关闭时保持应用程序处于活动状态,以便它可以在退出之前执行最终同步。我一直在使用 ThreadPool,直到我意识到退出应用程序会中止线程。
【解决方案3】:

我在生产代码中遇到过许多适合这样做的案例。所以,是的,在一行中定义和启动一个线程而不保留引用就可以了。我认为保留参考“以防万一”您以后重新设计并需要它,这违背了创建最简单的东西的原则。

而且,对于第二部分,不,它在运行时不会被 GC;线程是 Gtor 将从中追踪引用的根级对象。 Thread 实例只有在任何正在运行的线程(包括您在其上启动的线程)都无法访问时才会被 GCd。

并注意泄漏的 Thread 实例已创建但从未启动。我相信他们会永远闲逛。

【讨论】:

    【解决方案4】:

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

    【讨论】:

    • 基本上我会按照每约 5 分钟的时间表执行该行,并且担心它是否会泄漏,或者线程是否会正常运行。
    • 线程是否会泄漏(或者更糟的是,简单地循环到无穷大)取决于它正在执行的代码。是否可以剥离匿名线程取决于它将运行的代码。
    【解决方案5】:

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

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

    【讨论】:

      【解决方案6】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-20
        • 1970-01-01
        • 1970-01-01
        • 2019-09-12
        • 2011-07-01
        • 1970-01-01
        相关资源
        最近更新 更多