2011-06-09 29 views
3

我開發了一些工具來控制遊戲服務器的線程和正在使用的IDisposable「令牌」進行試驗,這樣我可以這樣使用代碼:在C#中對線程實用程序使用'using' - 何時Dispose被調用?

using(SyncToken playerListLock = Area.ReadPlayerList()) 
{ 
    //some stuff with the player list here 
} 

的想法是,我獲取讀鎖定一個區域內的玩家列表,當它與使用區塊不在同一範圍時,會自動解鎖。到目前爲止,這一切都已經實施和運作,但我擔心Dispose()的撥打時間。

是否SyncLock變量簡單地得到標誌着處置程序時離開using塊,然後獲得由垃圾收集器在某一點後清理,還是當前線程執行Dispose()方法離開using的一部分塊?

這種模式基本上是RAII,其中鎖是分配的資源。 Jon Skeet在他的MiscUtils中也使用了這種模式(即使用IDisposable「令牌」)的一個示例here

回答

11

using範圍退出後立即清除它。

在效果上,這

using(SyncToken playerListLock = Area.ReadPlayerList()) 
{ 
    //some stuff with the player list here 
} 

是語法糖

IDisposable playerListLock; 
try { 
    playerListLock = Area.ReadPlayerList(); 
} 
finally { 
    if (playerListLock != null) playerListLock.Dispose(); 
} 

using非常目的是使在C#,其中不確定性的功能破壞RAII樣功能。

2

Dispose()using塊退出時被稱爲immediataly。
using或多或少是C++中RAII語言的C#等價物。

0

只要您的變量超出範圍,垃圾收集器就會在稍後的某個未確定的點處啓動,並且不會影響此操作。

而且,看看本作的什麼情況下一個簡單的比較: using and IDisposable

3

Dispose被當您退出using的範圍內調用。語法糖:

MyObj instance = null; 
try 
{ 
    instance = new MyObj(); 
} 
finally 
{ 
    instance.Dispose(); 
} 
1

using文檔指出:

using語句確保 處置是即使當你調用對象的方法 發生異常 調用。通過將對象 置於try塊內,然後調用 在finally塊中處理,可以實現 的相同結果;實際上, 這是怎麼使用的語句是由編譯器翻譯的 。

所以是的,只要您退出該塊,它就會被調用。

1

在使用塊的末尾調用Dispose,您應該實現對SyncToken進行Dispose,以便可以確定性地釋放SyncLock,這是Dispose Pattern的完整點。

1

當您離開使用塊的範圍時,將調用Dispose()函數釋放分配的資源,但SyncToken由其運行的GC時間收集。

1

using塊是一個try-finally塊的只是一個語法糖:

using (var myObject = new MyObject()) 
{ 
    ... 
} 

等同於:

MyObject myObject = null; 

try 
{ 
    myObject = new MyObject(); 
    ... 
} 
finally 
{ 
    if (myObject != null) 
    { 
     myObject.Dispose(); 
    } 
} 

所以,你必須確信程序Dipose()將inmeadiately稱爲一旦你退出using塊。

一個完全不同的問題是當GC收集的對象。沒有保證何時會發生。