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