I've observed and AccessViolationException when running unit tests in parallel.
Investigating this I found out that creating multiple different databases, or even inserting new entities in a database, in parallel can cause this exception:
Fatal error. System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
at Devart.Data.SQLite.be.sqlite3_prepare_v2(IntPtr, IntPtr, Int32, IntPtr ByRef, IntPtr ByRef)
--------------------------------
at Devart.Data.SQLite.br.a(System.String, UInt32, System.String ByRef)
at Devart.Data.SQLite.bz.p()
at Devart.Data.SQLite.bb.o()
at Devart.Data.SQLite.bv.n()
at Devart.Data.SQLite.bv.i()
at Devart.Common.DbConnectionInternal.v()
at Devart.Common.DbConnectionFactory.b(Devart.Common.DbConnectionBase)
at Devart.Common.DbConnectionClosed.Open(Devart.Common.DbConnectionBase)
at Devart.Common.DbConnectionBase.i()
at Devart.Common.DbConnectionBase.Open()
at Devart.Data.SQLite.SQLiteConnection.Open()
at Devart.Common.Entity.cz.Open()
at Devart.Data.SQLite.Entity.s.Open()
at System.Data.Common.DbConnection.OpenAsync(System.Threading.CancellationToken)
at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenDbConnectionAsync(Boolean, System.Threading.CancellationToken)
at Microsoft.EntityFrameworkCore.Storage.RelationalConnection+<OpenInternalAsync>d__70.MoveNext()
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[Microsoft.EntityFrameworkCore.Storage.RelationalConnection+<OpenInternalAsync>d__70, Microsoft.EntityFrameworkCore.Relational, Version=8.0.7.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]](<OpenInternalAsync>d__70 ByRef)
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start[[Microsoft.EntityFrameworkCore.Storage.RelationalConnection+<OpenInternalAsync>d__70, Microsoft.EntityFrameworkCore.Relational, Version=8.0.7.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]](<OpenInternalAsync>d__70 ByRef)
at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenInternalAsync(Boolean, System.Threading.CancellationToken)
at Microsoft.EntityFrameworkCore.Storage.RelationalConnection+<OpenAsync>d__66.MoveNext()
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[Microsoft.EntityFrameworkCore.Storage.RelationalConnection+<OpenAsync>d__66, Microsoft.EntityFrameworkCore.Relational, Version=8.0.7.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]](<OpenAsync>d__66 ByRef)
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1[[System.Boolean, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].Start[[Microsoft.EntityFrameworkCore.Storage.RelationalConnection+<OpenAsync>d__66, Microsoft.EntityFrameworkCore.Relational, Version=8.0.7.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]](<OpenAsync>d__66 ByRef)
at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenAsync(System.Threading.CancellationToken, Boolean)
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand+<ExecuteNonQueryAsync>d__14.MoveNext()
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[Microsoft.EntityFrameworkCore.Storage.RelationalCommand+<ExecuteNonQueryAsync>d__14, Microsoft.EntityFrameworkCore.Relational, Version=8.0.7.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]](<ExecuteNonQueryAsync>d__14 ByRef)
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1[[System.Int32, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].Start[[Microsoft.EntityFrameworkCore.Storage.RelationalCommand+<ExecuteNonQueryAsync>d__14, Microsoft.EntityFrameworkCore.Relational, Version=8.0.7.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]](<ExecuteNonQueryAsync>d__14 ByRef)
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteNonQueryAsync(Microsoft.EntityFrameworkCore.Storage.RelationalCommandParameterObject, System.Threading.CancellationToken)
at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator+<MigrateAsync>d__15.MoveNext()
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator+<MigrateAsync>d__15, Microsoft.EntityFrameworkCore.Relational, Version=8.0.7.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]](<MigrateAsync>d__15 ByRef)
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start[[Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator+<MigrateAsync>d__15, Microsoft.EntityFrameworkCore.Relational, Version=8.0.7.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]](<MigrateAsync>d__15 ByRef)
at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.MigrateAsync(System.String, System.Threading.CancellationToken)
at Microsoft.EntityFrameworkCore.RelationalDatabaseFacadeExtensions.MigrateAsync(Microsoft.EntityFrameworkCore.Infrastructure.DatabaseFacade, System.Threading.CancellationToken)
at Stratec.LiaisonXXL.Adapters.Database.Tests.SqliteFeaturesTests+<>c+<<MultipleDbMigrationOnMultipleThreadsTest>b__4_0>d.MoveNext()
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.__Canon, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]](System.__Canon ByRef)
at Stratec.LiaisonXXL.Adapters.Database.Tests.SqliteFeaturesTests+<>c.<MultipleDbMigrationOnMultipleThreadsTest>b__4_0(Stratec.LiaisonXXL.Adapters.Database.Tests.RealSqliteTestDbOptionsFactory, System.Threading.CancellationToken)
at System.Threading.Tasks.Parallel+<>c__53`1+<<ForEachAsync>b__53_0>d[[System.__Canon, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext()
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Threading.Tasks.Parallel+<>c__53`1+<<ForEachAsync>b__53_0>d[[System.__Canon, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Threading.Tasks.Parallel, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<<ForEachAsync>b__53_0>d<System.__Canon> ByRef)
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start[[System.Threading.Tasks.Parallel+<>c__53`1+<<ForEachAsync>b__53_0>d[[System.__Canon, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Threading.Tasks.Parallel, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<<ForEachAsync>b__53_0>d<System.__Canon> ByRef)
at System.Threading.Tasks.Parallel+<>c__53`1[[System.__Canon, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].<ForEachAsync>b__53_0(System.Object)
at System.Threading.Tasks.Parallel+ForEachAsyncState`1+<>c[[System.__Canon, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].<System.Threading.IThreadPoolWorkItem.Execute>b__18_0(System.Object)
at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading.PortableThreadPool+WorkerThread.WorkerThreadStart()
A simple sample code to reproduce this looks like this:
await Parallel.ForEachAsync(
entitiesToInsert,
new ParallelOptions { MaxDegreeOfParallelism = 20},
async (entityToInsert, ct) =>
{
using var dbContext = new DbContext(
this.dbOptionsFactory.GetDbContextOptionsForTestDb<DbContext>());
dbContext.Add(entityToInsert);
await dbContext.SaveChangesAsync(ct);
});
The db connection has Pooling enabled and JournalMode set to WAL. The exception doesn't always happen so it may be a concurrency issue.