Question

I'm trying to wrap around Awesomium and make it look to the rest of my code as close as possible to NET's WebBrowser since this is for an existing application that already uses the WebBrowser.

In this library, there is a class called JSObject which represents a javascript object. You can get one of this, for instance, by calling the ExecuteJavascriptWithResult method of the WebView class. If you'd call it like myWebView.ExecuteJavascriptWithResult("document", string.Empty).ToObject(), then you'd get a JSObject that represents the document.

I'm writing an immutable class (it's only field is a readonly JSObject object) called JSObjectWrap that wraps around JSObject which I want to use as base class for other classes that would emulate .NET classes such as HtmlElement and HtmlDocument. Now, these classes don't implement Dispose, but JSObject does. What I first thought was to call the underlying JSObject's Dispose method in my JSObjectWrap's finalizer (instead of having JSObjectWrap implement Dispose) so that the rest of my code can stay the way it is (instead of having to add using's everywhere and make sure every JSObjectWrap is being properly disposed).

But I just realized if more than two JSObjectWrap's have the same underlying JSObject and one of them gets finalized this will mess up the other JSObjectWrap. So now I'm thinking maybe I should keep a static Dictionary of JSObjects and keep count of how many of each of them are being referenced by a JSObjectWrap but this sounds messy and I think could cause major performance issues.

Since this sounds to me like a common pattern I wonder if anyone else has a better idea.

Was it helpful?

Solution

To follow up on user1168577's answer, you could of course set the system up so there's a one to one relationship between wrappers and wrappees. Then (preferring composition over inheritance), have the library classes hold a reference to the same wrapper class, where appropriate. Then the garbage collector can do its magic.

But doing that its probably wasting your time. The standard pattern for IDisposable implementers calls Dispose in the finalizer, if it hadn't been called before. Decompile JSObject with ILSpy or similar to confirm that it does this. If it does, then there's no need for you to write code that also does that!

If you are sure your wrapper library will never be used for new code, then you don't even need to implement IDisposable; if it will be, then implement the interface, but allow the legacy code to omit calling Dispose unless you have to modify it for reasons.

OTHER TIPS

If more than 2 JSObjectWrap have the same underlying JSObject, there are more than 2 references referencing JSObject, so it won't be garbage collected until the reference count reaches 0. Am I missing something?

Edit after comment:

Ok. I get it. What you want to do is to be able to share JSObject but want to not dispose it as long as someone's referencing it. To me the only way out seems to be what you have suggested by keeping a dictionary of JSObjects. To draw a parallel, this is very similar to what .NET/JVM would do for immutable Strings that are shared with the only difference being that dispose in our example means garbage collection of a String here and unless the reference count is zero (which I guess cannot be determined unless a dictionary is maintained), a String is not eligible for garbage collection.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top