在C#中对线程实用程序使用'using' - 何时Dispose被调用?

问题描述:

我开发了一些工具来控制游戏服务器的线程和正在使用的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

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样功能。

Dispose()using块退出时被称为immediataly。
using或多或少是C++中RAII语言的C#等价物。

只要您的变量超出范围,垃圾收集器就会在稍后的某个未确定的点处启动,并且不会影响此操作。

而且,看看本作的什么情况下一个简单的比较: using and IDisposable

Dispose被当您退出using的范围内调用。语法糖:

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

using文档指出:

using语句确保 处置是即使当你调用对象的方法 发生异常 调用。通过将对象 置于try块内,然后调用 在finally块中处理,可以实现 的相同结果;实际上, 这是怎么使用的语句是由编译器翻译的 。

所以是的,只要您退出该块,它就会被调用。

在使用块的末尾调用Dispose,您应该实现对SyncToken进行Dispose,以便可以确定性地释放SyncLock,这是Dispose Pattern的完整点。

当您离开使用块的范围时,将调用Dispose()函数释放分配的资源,但SyncToken由其运行的GC时间收集。

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收集的对象。没有保证何时会发生。