litedb-async icon indicating copy to clipboard operation
litedb-async copied to clipboard

System.ObjectDisposedException: The semaphore has been disposed

Open sunnamed434 opened this issue 2 years ago • 2 comments

The problem is I use the hot reload in my project, and after the reloading of the project I re-create all instances of that I use, such as LiteDB, etc

simple Repro:

// On hot-reload load
protected override void Load()
{
    _liteDatabase = new LiteDatabaseAsync(databaseFilePath);
}
// On hot-reload unload
protected override void Unload()
{
    Instance = null;
    _liteDatabase?.Dispose();
}
// and at some runtime method if I'll try to use the _liteDatabase after the "reload" - I will get an exception about dispose

Expected behavior allows me to use the lite database when the new instance is created even if the previous instance was disposed

sunnamed434 avatar Aug 06 '23 14:08 sunnamed434

At first I thought this might be because it was not cleaning up the global state correctly when Dispose() was called. But that is tested here

https://github.com/mlockett42/litedb-async/blob/v0.1.7/LiteDBAsyncTest/BackgroundThreadTest.cs#L15

I think it is trying to use you disposed _liteDatabase after calling Unload but before calling Load. I also got an error about the semaphone if I tried to use a disposed LiteDatabaseAsync instance.

Can you try add the line

_liteDatabase = null;

To your Unload method.

I believe this will change the error you are getting to a null pointer error and show where this error is and in any case it is probably bad to leave the disposed carcasses of these old objects lying around.

Otherwise if this still causing problems make me a public repo which demonstrates the problem. I don't really know much about Hot Reload or how to get it to work so make sure you leave instructions. Also if it is a Mobile App I don't have iOS only Android.

mlockett42 avatar Aug 07 '23 12:08 mlockett42

The results are the same with this code:

protected override void Load()
{
    _liteDatabase = new LiteDatabaseAsync(databaseFilePath);
}
protected override void Unload()
{
    _liteDatabase?.Dispose();
    _liteDatabase = null;
}

Well, it's not a real "hot reload" and this is managed C# application running on Mono specifically Unity, the application is loading using Assembly.Load then creates the instance of the class and then method Load, and at any time user could use the command to reload/unload the specific "plugin", in case of reload will be called: Unload -> Load. On the server shutdown, all plugins will be forced to call Unload() method automatically (some kinda disposal)

The reason for the reloading is to update the configuration of the plugin from the .xml or reset the behavior of the "plugin"

sunnamed434 avatar Aug 07 '23 18:08 sunnamed434