根据我的所有阅读,应该有一个 GC 线程来调用所有终结器。现在的问题是这个“一个”线程的范围是什么 - 每个进程或每个应用程序域,因为域的整体目的是在一个进程空间中分离并创建“独立”的不同应用程序。
I read here http://dn.codegear.com/article/29365#MoreFinalizerIssues:
如果未处理的异常发生在
CLR 执行线程的终结器
将吞掉异常,治疗
终结器就像正常完成一样,
将其从脆弱队列中删除
并移至下一个条目。
但更严重的是,发生的事情
如果你的终结器没有退出
某些原因,例如它阻止,
等待一个永远不会发生的条件
发生。在这种情况下,终结器
线程将被挂起,所以不再有
可终结的对象将是垃圾
集。你应该非常
意识到这种情况并坚持
编写最简单的代码来释放你的
终结器中的非托管资源。
另一个考虑因素是会发生什么
在应用程序关闭期间。当。。。的时候
程序关闭,垃圾收集器
将尽力调用终结器
所有可终结的对象,但是
某些限制:
太多的帖子(甚至官方文档)滥用了术语“应用程序”、“进程”和“应用程序域”——其中大多数甚至假设它们是相等的,因为应用程序通常在单个进程的单个应用程序域中运行。这种滥用使得所有这些文档都难以阅读,甚至没有用处。
因此,我的问题假设有多个应用程序,每个应用程序在单个进程的单独应用程序域中运行。
所有这些应用程序是否共享相同的 GC 和终结器线程?上面文章中描述的问题(挂起终结器线程)是否会影响该进程中的所有应用程序?如果是 - 是否有解决方法(除了不使用不良应用程序之外),例如以某种方式发现终结器线程并将其发送 Thread.Abort?
以上都是因为我遇到了类似的问题。我的应用程序作为第三方软件(Outlook)的插件在单独的应用程序域中运行。由于各种原因,我需要调用 GC.Collect 和 GC.WaitForPendingFinalizers 来完全释放 COM 引用(通常的互操作例程对于 Office/Outlook 来说是不够的),当特定的其他第三方插件正在运行时,我的 GC.WaitForPendingFinalizers 永远挂起,所以我怀疑第三方添加中有一个“坏”终结器。我无法控制替换/删除该添加(客户的要求),所以我必须自己弄清楚如何使它们共存。
看起来,进程中的每个 CLR 实例确实只有一个线程——无论如何,目前是这样。下面是一些代码来表明:
Test.cs:
using System;
class Test
{
static void Main()
{
AppDomain.CreateDomain("First")
.ExecuteAssembly("ShowFinalizerThread.exe");
AppDomain.CreateDomain("Second")
.ExecuteAssembly("ShowFinalizerThread.exe");
}
}
ShowFinalizerThread.cs:
using System;
using System.Threading;
class ShowFinalizerThread
{
static Random rng = new Random();
~ShowFinalizerThread()
{
Console.WriteLine("Thread/domain: {0}/{1}",
Thread.CurrentThread.ManagedThreadId,
AppDomain.CurrentDomain.FriendlyName);
if (rng.Next(10) == 0)
{
Console.WriteLine("Hanging!");
Thread.Sleep(2000);
}
}
static void Main()
{
new Thread(LoopForever).Start();
}
static void LoopForever()
{
while (true)
{
new ShowFinalizerThread();
GC.Collect();
GC.WaitForPendingFinalizers();
Thread.Sleep(300);
};
}
}
将每个程序编译为控制台应用程序,然后运行 test.exe(在我看来,从命令行是最简单的)。您将看到一个应用程序域的终结器阻止了另一个应用程序域的终结器。
将来,如果每个线程都有一个终结器线程,我不会感到惊讶core而不是每个 AppDomain - 但听起来你仍然会遇到问题:(
当我在 Oracle Blob 中发现死锁时,我对您表示最深切的同情(尽管不是解决方案)。我们能够通过正确处理它来解决这个问题,但我知道并不是所有的东西都能很好地工作 - 即使找到它也是一种真正的痛苦!
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)