我正在开发一些实用程序来控制游戏服务器的线程,并尝试使用IDisposable
"令牌",这样我就可以使用这样的代码:
using(SyncToken playerListLock = Area.ReadPlayerList())
{
//some stuff with the player list here
}
这个想法是,我在一个区域的玩家列表上获得一个读取锁定,当它超出使用块的范围时,它会自动解锁。到目前为止,这一切都已实现并工作,但我担心调用Dispose()
的时间。
当程序离开using块时,SyncLock
变量是否只是被标记为待处理,然后在稍后的某个时刻被垃圾回收器清理,或者当前线程是否执行Dispose()
方法作为离开using
块的一部分?
这种模式基本上是RAII,其中锁是正在分配的资源。Jon Skeet在他的MiscUtils here
IDisposable
"令牌")在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的功能,它不具有确定性破坏的特点。
using
的作用域时,会调用Dispose
。的合成糖
MyObj instance = null;
try
{
instance = new MyObj();
}
finally
{
instance.Dispose();
}
using
块退出时,Dispose()
被立即调用using
或多或少是C++中RAII习语的C#等价物。
using
文档声明:
using语句确保即使出现异常也会调用Dispose在调用方法时发生在对象上。您可以实现通过放置对象获得相同的结果在try块内,然后调用在finally块中进行处理;事实上using语句就是这样的由编译器翻译。
所以,是的,只要你离开区块,它就会被调用。
Dispose在using块结束时被调用,您应该为SyncToken实现Dispose,这样SyncLock就可以被决定性地释放,这就是Dispose模式的全部意义。
当您离开using块的作用域时,会调用Dispose()函数来释放分配的资源,但是SyncToken在GC运行时由GC收集。
using
块只是try-finally
块的语法糖:
using (var myObject = new MyObject())
{
...
}
相当于:
MyObject myObject = null;
try
{
myObject = new MyObject();
...
}
finally
{
if (myObject != null)
{
myObject.Dispose();
}
}
因此,您可以确定,一旦您退出using
块,Dipose()将首先被调用。
一个完全不同的事情是当GC
收集对象时。不知道什么时候会发生。
一旦变量超出范围,就会调用Dispose方法,垃圾收集器稍后会在某个不确定的点启动,并且不会影响这一点。
此外,请查看以下内容,以便对下面发生的情况进行简单比较:使用和IDisposable