mbdavid / LiteDB

LiteDB - A .NET NoSQL Document Store in a single data file
http://www.litedb.org
MIT License
8.35k stars 1.22k forks source link

[BUG] This engine instance already disposed when using InsertBulk #2502

Closed mw911 closed 2 weeks ago

mw911 commented 2 weeks ago

Version Windows 10, >=5.0.20 (was working fine in 5.0.15), .Net Framework 4.6

Describe the bug After updating to the new version I get the exception LiteDB.LiteException: 'This engine instance already disposed'

Lets say I get 10 tasks and iterate through them then the exception comes on "Next" after processing the first Task object.

I think it has to do with the update of the TaskExecution collection in between but it was always working in at least 5.0.15. I updated to 5.0.20 because of bug #2351 A workaround is to declare listExecs before the For loop and do the InsertBulk afterwards. Nevertheless, it was working fine in 5.0.15 and it should not dispose the engine instance.

Code to Reproduce

Using db As New LiteDB.LiteDatabase($"Filename={DBLiteName};connection=shared")
Dim tasks = db.GetCollection(Of Task)("Task").FindAll
Dim execs = db.GetCollection(Of TaskExecution)("TaskExecution")

For Each myTask As Task In tasks
    Dim listExecs As New List(Of TaskExecution)
    Dim hist As New TaskExecution With {
        .TaskID = myTask.Id
    }
    listExecs.Add(hist)
    execs.InsertBulk(listExecs)
Next
End Using

Expected behavior Code should iterate through all Tasks found and insert objects of type TaskExecution to the collection

ScreenshotsStackTrace: LiteDB.LiteException HResult=0x80131500 Message=This engine instance already disposed. Source=LiteDB StackTrace: at LiteDB.Engine.EngineState.Validate() at LiteDB.BsonDataReader.Read() at LiteDB.SharedDataReader.Read() at LiteDB.LiteQueryable1.<ToDocuments>d__26.MoveNext() at System.Linq.Enumerable.WhereSelectEnumerableIterator2.MoveNext()

JKamsker commented 2 weeks ago

Are you able to reproduce the error without sharedmode?

mw911 commented 2 weeks ago

Hi Jonas It looks like I was using LiteDB incorrectly. Up until version 5.0.15 I was successfully using the code below without the "ToList" function. According to the official documentation, I should have used ToList. Not sure why it was working in earlier versions or maybe not using ToList was based on a comment a read somewhere in order to improve performance or reduce memory consumption - I can't remember. I updated my code and no further problems so far. In addition, the other Issue #2351 no longer occurs.

Dim tasks = db.GetCollection(Of Task)("Task") For Each tsk As Task In tasks.FindAll.ToList tasks.Update(tsk) Next

Many thanks Martin