1

我正在尝试环绕Awesomium并使其看起来尽可能接近 NET 的其余代码,WebBrowser因为这是针对已经使用WebBrowser.

在这个库中,有一个名为的类JSObject,它代表一个 javascript 对象。例如,您可以通过调用类的ExecuteJavascriptWithResult方法来获得其中之一WebView。如果你把它叫做 like myWebView.ExecuteJavascriptWithResult("document", string.Empty).ToObject(),那么你会得到一个JSObject代表文档的。

我正在编写一个不可变的类(它的唯一字段是一个readonly JSObject对象)JSObjectWrapJSObject我想将其用作其他类的基类,这些类将模拟 .NET 类,例如HtmlElementHtmlDocument。现在,这些类不实现Dispose,但是实现了JSObject。我首先想到的是在我的终结器中调用底层JSObjectDispose方法(而不是实现),以便我的其余代码可以保持原样(而不是必须在任何地方添加 ' 并确保每个都是妥善处置)。JSObjectWrapJSObjectWrapDisposeusingJSObjectWrap

但我刚刚意识到,如果两个以上JSObjectWrap的具有相同的基础JSObject,其中一个得到最终确定,这将搞砸另一个JSObjectWrap。所以现在我在想也许我应该保持一个静态DictionaryJSObjects计算它们中的每一个被 a 引用了多少,JSObjectWrap但这听起来很混乱,我认为可能会导致主要的性能问题。

由于这对我来说听起来像是一种常见的模式,我想知道是否还有其他人有更好的主意。

4

2 回答 2

1

要跟进 user1168577 的回答,您当然可以设置系统,以便包装器和被包装器之间存在一对一的关系。然后(更喜欢组合而不是继承),让库类在适当的情况下持有对同一包装类的引用。然后垃圾收集器可以发挥它的魔力。

但这样做可能会浪费你的时间。IDisposable 实现者的标准模式在终结器中调用 Dispose,如果它之前没有被调用的话。使用 ILSpy 或类似工具反编译 JSObject 以确认它是否执行此操作。如果是这样,那么您就无需编写也可以做到这一点的代码!

如果您确定您的包装库永远不会用于新代码,那么您甚至不需要实现 IDisposable;如果是,则实现该接口,但允许遗留代码省略调用 Dispose,除非您出于某种原因必须对其进行修改。

于 2012-07-04T03:46:39.433 回答
1

如果超过 2 个 JSObjectWrap 具有相同的底层 JSObject,则引用 JSObject 的引用超过 2 个,因此在引用计数达到 0 之前不会被垃圾收集。我错过了什么吗?

评论后编辑:

好的。我得到它。您想要做的是能够共享 JSObject 但只要有人引用它就不想处置它。对我来说,唯一的出路似乎是您建议保留 JSObjects 字典。为了绘制一个平行线,这与 .NET/JVM 对共享的不可变字符串所做的非常相似,唯一的区别是在我们的示例中 dispose 意味着在这里对字符串进行垃圾收集,除非引用计数为零(我除非维护字典,否则无法确定猜测),字符串不符合垃圾收集条件。

于 2012-07-04T03:14:41.227 回答