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