.net – 每個應用程式域或每個程序的終結器執行緒的範圍是什麼?
基於我所有的閱讀,應該有一個GC執行緒來呼叫所有的終結器.現在,問題是這個“一個”執行緒 – 每個程序或每個應用程式域的範圍是什麼,因為域的全部意圖是在一個程序空間中分離和使“獨立”不同的應用程式.
我讀了ofollow,noindex" target="_blank">here :
If an unhandled exception occurs in a
finalizer the CLR’s executing thread
will swallow the exception, treat the
finalizer as if it completed normally,
remove it from the freachable queue
and move onto the next entry.
More serious though, is what happens
if your finalizer doesn’t exit for
some reason, for example it blocks,
waiting for a condition that never
In this case the finalizer
thread will be hung, so no more
finalizable objects will be garbage
You should be very muchaware of this situation and stick to
writing the simplest code to free your
unmanaged resources in finalizers.
Another consideration is what happens
during application shutdown. When the
program shuts, the garbage collector
will endeavour to call the finalizers
of all finalizable objects, but with
certain limitations:
-
Finalizable objects are not promoted
to higher heap generations during
shutdown.
-
Any individual finalizer will have a
maximum of 2 seconds to execute; if it
takes longer it will be killed off.
-
There is a maximum of 40 seconds for
all finalizers to be executed; if any
finalizers are still executing, or
pending at this point the whole
process is abruptly killed off.
濫用術語“應用程式”,“程序”和“應用程式域”的帖子太多(甚至是官方文件) – 大多數文件甚至假定它們相等,因為通常應用程式在單個應用程式域中執行.這種濫用使得所有這些文件難以閱讀,甚至沒有用處.
所以,我的問題假設不止一個應用程式,每個應用程式在單個程序中的單獨的應用程式域中執行.
所有這些應用程式是否共享相同的GC和終結器執行緒?上述文章中描述的問題(掛起終結器執行緒)是否會影響該程序中的所有應用程式?如果是 – 有沒有解決方法(除了不使用壞的應用程式),以某種方式發現finalizer執行緒併發送Thread.Abort?
以上都是因為我遇到類似的問題.我的應用程式在單獨的應用程式域中執行,作為第三方軟體(Outlook)的外掛.由於各種原因,我需要呼叫GC.Collect和GC.WaitForPendingFinalizers來完全釋放COM引用(通常的interop例程不足以用於Office / Outlook),當一個特定的其他第三方addin正在執行時,我的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(從命令列最簡單的是IMO).您會看到一個應用程式域名的終結者阻止了另一個.
在將來,我不會驚訝地看到每個核心而不是每個AppDomain的一個終結者執行緒 – 但是聽起來你仍然會遇到問題:(
你有我最深切的同情(雖然不是一個解決方案) – 一旦我跟蹤了一個Oracle Blob的僵局.我們可以通過妥善處理來解決這個問題,但是我不知道一切工作都很好 – 甚至找到一個真正的痛苦!
http://stackoverflow.com/questions/241537/what-is-the-scope-of-finalizer-thread-per-application-domain-or-per-process