我知道一個using
塊可以確保IDisposable
被「使用」的對象將被放置在該塊的末尾 - 但是保證該對象在此之前不會被處置嗎?使用塊是否保證該對象不會被丟棄,直到塊結束?
換句話說,如果我有:
using (new DisposableObject()) {
// blah blah
}
我可以肯定的是,DisposableObject
不會被佈置直到塊結束,或者可能會在垃圾收集器檢測到我有沒有它的控制器在塊內,並立即處置它?
我知道一個using
塊可以確保IDisposable
被「使用」的對象將被放置在該塊的末尾 - 但是保證該對象在此之前不會被處置嗎?使用塊是否保證該對象不會被丟棄,直到塊結束?
換句話說,如果我有:
using (new DisposableObject()) {
// blah blah
}
我可以肯定的是,DisposableObject
不會被佈置直到塊結束,或者可能會在垃圾收集器檢測到我有沒有它的控制器在塊內,並立即處置它?
您的對象只會被放置一次,在使用塊結束之前不會GC'd。
規範保證了當你有using (expression) statement
和表達式的類型是可空類型(稱之爲ResourceType
),那麼它擴展成:
{
ResourceType resource = expression;
try {
statement;
}
finally {
if (resource != null) ((IDisposable)resource).Dispose();
}
}
Dispose
將在塊的末尾被調用一次並有一個本地生成的,保持對你的一次性對象的引用。本地防止在使用塊結束之前對象被GC'd。
不,它不。沒有什麼從做阻止你:
using(var myObject = new DisposableObject())
{
myObject.Dispose();
}
究竟會在這種情況下發生取決於DisposableObject
語義。它可能會拋出一個異常,或者可能對被調用兩次的Dispose
非常滿意。
應該指出,對象處置和垃圾收集是完全不同的概念。僅僅因爲物體被丟棄並不意味着它會被垃圾收集,而只是因爲物體被垃圾收集並不意味着它會被丟棄。
一旦對象的所有引用被銷燬或無法訪問,對象就可能被垃圾回收。代碼在using
-block內運行時不會發生這種情況,因爲塊本身具有對該對象的引用。
我想你錯過了這個問題的關鍵。問題在於如果GC在使用塊結束之前調用終結器。 – CodesInChaos
+1感謝您對垃圾收集和物體處理進行區分,這在我之前並不清楚。因此,重新翻譯我的問題:在我的問題的代碼中,我可以依賴'DisposableObject'在'using'塊的末尾之前不被*處理嗎? –
@Shaul沒有辦法保證在使用塊結束之前不會放置變量myObject。在所有引用無法訪問之後,該對象可能會被釋放,但是當您在使用塊中時,不會發生這種情況,因爲您在那裏有一個引用。 –
我認爲你寧願想知道垃圾收集而不是處置。
垃圾收集器不會收集using
塊內的對象。即使你專門調用Dispose
方法,仍然有一個積極的參考,所以它不會被收集。
爲using
塊生成的代碼以檢查對象是否可以丟棄結束,以便在using
塊中使用該對象以保持活動狀態。
+1這是最明確的解釋,值得回答。謝謝! –