不要以为到了DotNet时代就不需要引用计数了。
COM时代的引用计数是兼并资源与内存回收于一体的方案。可惜非常难维护。并且解决不了引用链的问题。
DotNet时代的垃圾回收,只是内存的回收方案。它在回收对象时通过Finalize来通知对象,该收集资源了。可惜这个可能导致回收资源的延迟。。
就好象你Open一个SqlConnection,不Close它,而直接放弃它的引用。那么你就只好等GC收拾它了。可惜一个数据库连接就在回收前白白地浪费掉了。
DotNet提出一个方案,叫 IDisposable 。实现这个接口的类,告诉使用它的人,当你不要我的时候,麻烦先Dispose我。
可惜问题仍然还是在的。你不要这个类,不代表别人不要啊。你把它Dispose掉,那么别人怎么办?
通常,你要Dispose一个对象,一个很充分的理由是,到最后只有你使用这个对象。这需要编程人员很清楚某个对象是不是只有自己再使用。
不过电脑的发展很快啊。各种各样的模式在不断地出。到了某个时候,一个对象哪里来的,到哪里去,还重要吗?
大家认为,计算机以后的发展是不是,“程序员越来越不知道一个模式具体怎么运行的,只知道就按某个的规则做就对了”?
就好像这样的编码:{
往 $TABLENAME 这个表里插入界面上的数据
}
到底 SqlConnection 怎么来的。由谁来释放它已经不重要了。或者它不会被立刻释放,而转给另外一个地方个处理。而且这个步骤极有可能是被某个事务所操纵着的。
可惜程序员不需要理会这个了。他的职责就是把界面上的数据录入到数据库这个事实告诉给编译器。当2004年的你问起这个未来的程序员,那个语句是运行了什么代码。那个程序员就会答你:“我最讨厌写代码的人在我面前炫耀他那低效率的玩意了!”
(就好象我们不太喜欢写汇编的人一样)
我目前在写一个叫 Scoping 的东西。这个东西基于 ContextBoundModel 来实现。
它的概念和COM+的Context有点象。不过不是同一个东西。它是基于 Context 的概念实现的。(就好象TcpClient是基于Socket的一样)
它的目标是,在你需要一个对象的时候,它就有。在真正没有人需要那对象的时候,那对象能自动消失。不同的对象/代码在运行的时候得到的所依赖的同一种对象有可能不是同一个实例。例如一个窗口中,左边是简体,而右边是繁体。当然这个也要自动实现。
也就是说 Scoping 努力做到一个框架,这个框架能释放程序员管理相关资源/对象的工作。这一点是和AOP的思想一致的。Scoping算是AOP的一种应用。
到时候,你就不需要知道一个数据库连接是怎么来的了。一个往数据库录入数据的模块不应该关心数据库怎样连上的。它应该专著于:把DotNet数据转化为SqlParameter然后执行语句。
但是目前的难题,就像文章所说的,就是资源引用问题。一个方法被执行后,假如外界环境知道某些资源是在方法中自动创建的,那外界环境怎样知道方法执行期间,是否有其他的对象仍然使用这个资源?
(例如虽然方法返回了,仍然有异步调用的代码在使用着那些资源)
或者我要用引用计数的办法了。但是我希望能得到好的建议。谢谢。