1
Vote

Getting ObjectDisposedException on V8NativeObject finalizer

description

Hi,

I'm getting this weird behavior when disposing a V8Engine object instance.

System.ObjectDisposedException: Safe handle has been closed
at System.Runtime.InteropServices.SafeHandle.DangerousAddRef(Boolean& success)
at System.StubHelpers.StubHelpers.SafeHandleAddRef(SafeHandle pHandle, Boolean& success)
at Microsoft.Win32.Win32Native.SetEvent(SafeWaitHandle handle)
at System.Threading.EventWaitHandle.Set()
at V8.Net.ObservableWeakReference`1.DoFinalize(T obj)
at V8.Net.V8NativeObject.Finalize()

This is how I'm disposing the engine instance:
public void Dispose() 
{
    engine.ForceV8GarbageCollection();
    engine.Dispose();
    engine = null;

    GC.Collect();
}
Since this occurs on the Finalizer thread, this crashes my application completely and there's no way of handing the exception. Am I doing something wrong? Is there a special way of disposing the V8Engine?

I'm using the latest release of V8.NET on a 64bit machine.

Thank you :)

comments

jamesnw wrote Mar 29 at 1:48 AM

Good question, I don't think it was designed to be called within a finalizer thread separate from the main thread (perhaps an oversight; I assume you have an engine wrapper?). If not, try to recreate your issue in a smaller wrapper class and zip and send it, thanks.

geodanila89 wrote Mar 29 at 7:31 AM

http://stackoverflow.com/questions/20358401/throwing-exception-in-finalizer-to-enforce-dispose-calls

From my understanding it's considered a bad practice to throw exceptions from finalizers (in this example the finalizer for the V8NativeObject class throws an exception when trying calling the DoFinalize method on the ObservableWeakReference instance).

Finalizers are always called by the runtime on a different thread - if an exception occurs while running this code it will always crash the running Process. (I am calling Dispose on the main thread but the finalizer is called by the runtime so I have no control over it)

I think it would be best to wrap the finalizer code in a try-catch block, to avoid throwing exceptions.

I will try to reproduce the issue in a small project.

jamesnw wrote Mar 29 at 5:08 PM

I agree, and certainly throwing exceptions in there is not by design. If it is throwing exceptions, it may be there during past debugging - VS can catch first chance exceptions if you configure it properly. I'll take a look asap.

jamesnw wrote Apr 5 at 8:13 AM

I think you have an old version. The new version I've been working on in the development branch doesn't have any 'ObservableWeakReference' type anymore. It's a complete re-write in many places and is much more stable. I ran a bunch of tests without issues. In fact, the console project has a \newenginetest command that runs 3 engines and disposes of them. After more testing I'll update CodePlex for the last time and start making my changes and release on the GitHub one instead. I'll make another comment when done.

geodanila89 wrote Apr 5 at 9:26 AM

That might be possible - I was using the latest release from Codeplex (V8.NET Release v1.5.19.37) for my tests. Thank you for your help, it's much appreciated!

jamesnw wrote Apr 5 at 5:08 PM

Yeah, sorry, haven't updated it in awhile since the major changes.