CoreyKaylor / Lightning.NET

.NET library for LMDB key-value store
Other
398 stars 82 forks source link

Finalizer throws exception #101

Closed et1975 closed 7 years ago

et1975 commented 7 years ago

System.InvalidOperationException: The LightningEnvironment was not disposed and cannot be reliably dealt with from the finalizer at LightningDB.LightningEnvironment.Dispose (System.Boolean disposing) at LightningDB.LightningEnvironment.Finalize () exception inside UnhandledException handler: Safe handle has been closed

Expected: Dispose should not throw an exception. Finalizers are run on a separate thread and there's no good way to recover.

https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/dispose-pattern

nblumhardt commented 7 years ago

@et1975 what's causing the environment to end up on the finalizer thread in this case - is there a missing using block or Dispose() call earlier in the application?

et1975 commented 7 years ago

@nblumhardt I got this stack trace (in its entirety) when I woke up my machine running a topshelf service as a console app, it must have tried to exit. I was under the impression that environment initialization is costly, so my environment is lazy-initialized once and stored in a static var and there's no using block.

nblumhardt commented 7 years ago

:+1: in TopShelf, using a WhenStopped() block to close the environment would work here.

(The exception from the finalizer is a bit heavy-handed :-) but it's indicating an important bug fix is needed; there's no way for the interop library to correctly shut down the environment from the finalizer thread, so blowing up - rather than silently failing - seems less surprising in the long run, to me.)

et1975 commented 7 years ago

I guess I don't understand why it's important to dispose the environment since the app is closing (and I'm assuming all writes are done within a transaction), but I'll take it as "by design". Thanks, closing.