编辑:(由数字6解决)
当多个线程同时访问我的System.AccessViolationException
时,是什么导致SQLitePCLRaw.provider.e_sqlite3.dll中的System.ExecutionEngineException
或FooDbContext
崩溃?
我有一个使用NETstandard 2.0.3,Microsoft.EntityFrameworkCore 2.2.4,Microsoft.EntityFrameworkCore.Sqlite 2.2.4支持UWP,Android和iOS的Xamarin Forms应用程序(3.5.0.169047),并且我遇到了可重现的崩溃情况(它确实发生在UWP上)我无法解决同时从两个不同线程同时访问设备上的sqlite数据库期间出现的问题。我有一个同步过程(将本地数据推送到API并从API提取在线数据)可能需要一分钟左右的时间,因此我需要在单独的线程中执行以使UI在其操作期间保持响应。我还需要允许在同步期间查询本地数据,以允许在同步期间进行导航或在同步期间在应用程序内进行其他只读数据操作。如果我在同步过程中未执行任何数据访问操作,则长时间运行的同步工作会很好,但是在完成任何中断的较短数据访问操作后立即崩溃。
从Visual Studio 2017(v15.9.5)的Debug输出中可以看出,以下是我所见的两个崩溃异常(可能与定时相关,导致相同的复制崩溃)。
尝试读取或写入 protected 内存。这通常表明其他内存已损坏。
调试时,没有有关该异常的其他详细信息;它发生在同步代码的不同长时间运行的行中,具体取决于执行中断操作的时间;调试器显示发生异常的长时间运行代码都包含在
Try { ... } Catch(Exception) { ... }
尝试在我的代码中进行阻止。可能是什么原因造成的,我该如何解决?
我已经经历了以下所有方面:
Microsoft.Data.Sqlite.SQLiteConnection
信息时确定的。 Microsoft.Data.Sqlite.SqliteConnectionStringBuilder
修改了我的连接字符串,以根据每个数据访问的需要使用适当的Mode
(SqliteOpenMode.ReadOnly
或SqliteOpenMode.ReadWriteCreate
)。 FooDbContext
的Dispose()
摆脱了长时间运行的线程的FooDbContext
所依赖的资源吗?Dispose
中的FooDbContext
方法不执行任何操作,甚至不调用基类的Dispose
(不建议使用,但我暂时尝试过)时,崩溃仍然发生。 Microsoft.Data.Sqlite.SqliteConnectionStringBuilder
或Microsoft.Data.Sqlite.SQLiteConnection
或Microsoft.EntityFrameworkCore.DbContextOptionsBuilder
的UseSqlite
函数设置一项设置,以确保使用了序列化模式(我目前还不能100%地确定使用了该模式)?编辑:为我解决了这个问题的答案:
SQLitePCL.Batteries_V2.Init();
的调用选择了要使用的特定于平台的低级SQLite提供程序。这可能是错误的吗?SQLitePCL.Batteries_V2.Init
的调用仅打算在每个平台上进行一次(在平台特定的代码中,或者在共享代码中,只要在共享项目中还安装了Microsoft.EntityFrameworkCore.Sqlite
,作为每个平台的特定项目)。我的SQLitePCL.Batteries.Init
用法错误地在OnConfiguring
的FooDbContext
内部,这使得它在每次配置FooDbContext
时调用一次,而不是在每次应用程序启动时调用一次。 将SQLitePCL.Batteries_V2.Init();
行从OnConfiguring
中移出,并移到我的共享项目中的App.xaml.cs
构造函数中,对此进行了修复!在中断线程的数据访问之后,不再发生崩溃。 我真的希望这可以为某人节省大量的麻烦,而这又使我避免陷入困境。 最佳答案
为我解决了这个问题的答案:
SQLitePCL.Batteries_V2.Init();
的调用选择了要使用的特定于平台的低级SQLite提供程序。这可能是错误的吗?SQLitePCL.Batteries_V2.Init
的调用仅打算在每个平台上进行一次(在平台特定的代码中,或者在共享代码中,只要在共享项目中还安装了Microsoft.EntityFrameworkCore.Sqlite
,作为每个平台的特定项目)。我的SQLitePCL.Batteries.Init
用法错误地在OnConfiguring
的FooDbContext
内部,这使得它在每次配置FooDbContext
时调用一次,而不是在每次应用程序启动时调用一次。 将SQLitePCL.Batteries_V2.Init();
行从OnConfiguring
中移出,并移到我的共享项目中的App.xaml.cs
构造函数中,对此进行了修复!在中断线程的数据访问之后,不再发生崩溃。 我真的希望这可以为某人节省大量的麻烦,而这又使我避免陷入困境。