我正在尝试回绕Awesomium
并使其看起来尽可能接近我的代码WebBrowser
,因为这是针对已经使用{{1}的现有应用程序}}。
在这个库中,有一个名为WebBrowser
的类,它代表一个javascript对象。例如,您可以通过调用JSObject
类的ExecuteJavascriptWithResult
方法来获取其中一个。如果您将其称为WebView
,那么您将获得代表该文档的myWebView.ExecuteJavascriptWithResult("document", string.Empty).ToObject()
。
我正在编写一个名为JSObject
的不可变类(它的唯一字段是readonly JSObject
对象),它包含JSObjectWrap
,我希望将其用作其他类的基类。模拟.NET类,例如JSObject
和HtmlElement
。现在,这些类不实现HtmlDocument
,但Dispose
实现。我首先想到的是在JSObject
的终结器中调用基础JSObject
的{{1}}方法(而不是让Dispose
实现JSObjectWrap
),这样才能我的其余代码可以保持原样(不必在任何地方添加JSObjectWrap
,并确保每个Dispose
都得到妥善处理。
但我刚刚意识到,如果两个以上的using
具有相同的基础JSObjectWrap
并且其中一个被最终确定,那么这将使另一个JSObjectWrap
陷入困境。所以现在我想也许我应该保持JSObject
JSObjectWrap
的静态Dictionary
,并且计算JSObjects
引用它们的数量,但这听起来很混乱,我认为可能会导致重大性能问题。
因为这听起来像一个普通的模式,我想知道是否有其他人有更好的主意。
答案 0 :(得分:1)
如果超过2个JSObjectWrap具有相同的底层JSObject,则有超过2个引用引用JSObject,因此在引用计数达到0之前它不会被垃圾收集。我错过了什么?
评论后编辑:
确定。我知道了。你想要做的是能够共享JSObject但是只要有人引用它就不想处理它。对我来说,唯一的出路似乎就是你建议保留JSObjects的字典。要绘制并行,这与.NET / JVM将为不可变的字符串做的非常类似,只有在我们的示例中的dispose意味着在这里对String进行垃圾收集并且除非引用计数为零(我是除非维护字典,否则无法确定猜测,字符串不符合垃圾收集的条件。
答案 1 :(得分:1)
要跟进user1168577的回答,您当然可以设置系统,以便在包装器和包装之间建立一对一的关系。然后(更喜欢组合而不是继承),让库类在适当的时候保存对同一个包装类的引用。然后垃圾收集器可以发挥它的魔力。
但这样做可能会浪费你的时间。 IDisposable实现者的标准模式在终结器中调用Dispose,如果之前没有调用过的话。用ILSpy或类似程序反编译JSObject以确认它是这样做的。如果确实如此,则无需编写也的代码!
如果您确定您的包装库永远不会用于新代码,那么您甚至不需要实现IDisposable;如果是,则实现接口,但允许遗留代码省略调用Dispose,除非你因为原因需要修改它。