【问题标题】:C# Managed Thread CleanupC# 托管线程清理
【发布时间】:2009-02-10 20:25:01
【问题描述】:

在我的应用程序使用ParameterizedThreadStart 委托创建线程后,该线程执行一些初始化并运行完成。稍后,我可以观察到该线程不再处于活动状态,因为它的IsAlive 属性为假,而ThreadState 属性为ThreadState.Stopped

一旦线程达到此状态,它们就会保留在我的应用程序中,仍然作为线程对象存在,直到我的应用程序关闭。一旦它们不再活跃,我可以采取任何步骤来处理它们吗?我想删除该对象并取消分配任何资源,以便在任何给定时刻我拥有的唯一线程对象都是活动线程。但是,Thread 没有实现 IDisposable,所以我不确定我应该如何做到这一点。

【问题讨论】:

    标签: c# .net multithreading


    【解决方案1】:

    您在代码中保留对线程的引用。

    如果您编写了将检查线程状态的代码,那么该代码本质上将使线程对象保持活动状态,直到 GC 收集它。

    一旦你完成了一个线程,或者如果你不需要访问它,确保你对它的所有引用都清空。线程没有实现 IDisposable,因为正如您已经明确指出的那样,这对线程没有意义。

    线程是 .Net 中的原生线程,因此您不必担心泄漏。如果您确定它们会停止,那么一旦您确定它已经完成,就将它们从您的列表中删除。

    【讨论】:

    • 我认为可能是这种情况,所以我尽力删除了对该对象的所有引用。使用 VS 调试器,我定期检查线程的状态,它仍然是一个有效的线程对象。我想这意味着我还在某处引用它?
    • 一旦附加了调试器,GC就不会接触到对象了:(
    • 没错。使用 MEMORY PROFILER 检查 GC 问题。永远不要使用调试器,因为它会出于明显的原因改变 GC 行为(例如,让变量保持更长时间,以便它们仍然可以看到)。
    • 我意识到我应该提到使用“Thread.Join()”超时。 Join 将等到线程完成。如果您从逻辑上知道它应该停止,您可以在超时后加入它,然后在它不能可靠停止时采取一些措施。
    【解决方案2】:

    听起来您需要放弃对Thread 对象的引用,以便垃圾收集器可以丢弃它。只需将您必须的引用设置为 null,然后让 GC 在准备就绪时执行其工作。

    根据您的情况,您可能希望使用WeakReference(或我的朋友赛勒斯的WeakReference<T>)。

    【讨论】:

      【解决方案3】:

      非托管线程是否仍然存在,线程是否真的从其 ParameterizedThreadStart 方法返回?也尝试使 IsBackground = false

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-11-12
        • 1970-01-01
        • 1970-01-01
        • 2016-07-27
        • 1970-01-01
        • 2013-05-12
        • 1970-01-01
        相关资源
        最近更新 更多