c#Xamarin SQLite.Net序列化模式工作不正常?

c#Xamarin SQLite.Net序列化模式工作不正常?,c#,multithreading,sqlite,xamarin,serialization,C#,Multithreading,Sqlite,Xamarin,Serialization,我正在Android和iOS中使用库SQLite.Net PCL,刚刚遇到一个错误。也许我误解了什么,但SQLite文档说明: 已序列化。在序列化模式下,SQLite可以由多个用户安全使用 没有限制的线程 然而,当我通过几个线程共享一个连接时,似乎出现了一些问题 我写了一个测试应用程序。见下文 通过“同步”插入,我得到了SQLite.Net.SQLiteException:missage 以下是完全例外: SQLite.Net.SQLiteException:在 SQLite.Net.Prepa

我正在Android和iOS中使用库SQLite.Net PCL,刚刚遇到一个错误。也许我误解了什么,但SQLite文档说明:

已序列化。在序列化模式下,SQLite可以由多个用户安全使用 没有限制的线程

然而,当我通过几个线程共享一个连接时,似乎出现了一些问题

我写了一个测试应用程序。见下文

通过“同步”插入,我得到了SQLite.Net.SQLiteException:missage

以下是完全例外:

SQLite.Net.SQLiteException:在 SQLite.Net.PreparedSqlLiteInsertCommand.ExecuteOnQuery (系统对象[]源)[0x0016b]位于 :0 at SQLite.Net.SQLiteConnection.Insert(System.Object obj,System.String 额外,系统类型objType)[0x000fc]输入 :0 at SQLite.Net.SQLiteConnection.Insert(System.Object obj)[0x00012]位于 :0 at test.TestTask+c__显示类4_0.b__0(System.Object aName) [0x00052]in/Users/dev/Documents/Xamarin/TestRepo/test/TestTask.cs:49

如果您事后查看数据库,甚至会发现有重复的记录

因此,我的问题是:序列化模式是否设计为在多个线程中使用单个连接?或者它是SQLite库中的一个bug

TestTask.cs(由Android和iOS共享):

using System;
using System.Threading.Tasks;
using SQLite.Net;
using SQLite.Net.Attributes;
using SQLite.Net.Interop;

namespace test
{
    [Table("test_class")]
    public class TestClass
    {
        [PrimaryKey, AutoIncrement, Column("_id")]
        public int Id { get; set; }

        [Column("caption")]
        public string Caption { get; set; }
    }

    public static class TestTask
    {
        static Task taskA;
        static Task taskB;

        public delegate void OnMessage(string msg);

        public static void Init(ISQLitePlatform platform, string path, OnMessage onMsg)
        {
            var con = new SQLiteConnection(platform, path);
            con.CreateTable<TestClass>();
            taskA = GetTask("First", con, onMsg);
            taskB = GetTask("Second", con, onMsg);
        }

        static Task GetTask(string name, SQLiteConnection connection, OnMessage onMsg)
        {
            return new Task((aName) =>
            {
                int i = 0;
                onMsg("Start " + aName);
                for (i = 0; i < 1000; i++)
                {
                    var obj = new TestClass
                    {
                        Caption = i + ": " + DateTime.Now.ToString("dd.MM.yyyy HH:mm:ss:fff")
                    };

                    try
                    {
                        connection.Insert(obj);
                    }
                    catch (Exception e)
                    {
                        onMsg(aName + " -> " + "Index: " + i + " Error: " + e.Message);
                    }
                }
                onMsg("End " + aName);
            },name);
        }

        public static void Run()
        {
            taskA.Start();
            taskB.Start();
        }
    }
}
    void HandleOnMessage(string msg)
    {
        UIApplication.SharedApplication.InvokeOnMainThread(() => Console.WriteLine(msg));
    }

    void DoIt()
    {
        var platform = new SQLite.Net.Platform.XamarinIOS.SQLitePlatformIOS();
        platform.SQLiteApi.Config(ConfigOption.Serialized);

        var path = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
        path = Path.Combine(path, "test.db");

        TestTask.Init(platform, path, HandleOnMessage);
        TestTask.Run();
    }
其他信息:

using System;
using System.Threading.Tasks;
using SQLite.Net;
using SQLite.Net.Attributes;
using SQLite.Net.Interop;

namespace test
{
    [Table("test_class")]
    public class TestClass
    {
        [PrimaryKey, AutoIncrement, Column("_id")]
        public int Id { get; set; }

        [Column("caption")]
        public string Caption { get; set; }
    }

    public static class TestTask
    {
        static Task taskA;
        static Task taskB;

        public delegate void OnMessage(string msg);

        public static void Init(ISQLitePlatform platform, string path, OnMessage onMsg)
        {
            var con = new SQLiteConnection(platform, path);
            con.CreateTable<TestClass>();
            taskA = GetTask("First", con, onMsg);
            taskB = GetTask("Second", con, onMsg);
        }

        static Task GetTask(string name, SQLiteConnection connection, OnMessage onMsg)
        {
            return new Task((aName) =>
            {
                int i = 0;
                onMsg("Start " + aName);
                for (i = 0; i < 1000; i++)
                {
                    var obj = new TestClass
                    {
                        Caption = i + ": " + DateTime.Now.ToString("dd.MM.yyyy HH:mm:ss:fff")
                    };

                    try
                    {
                        connection.Insert(obj);
                    }
                    catch (Exception e)
                    {
                        onMsg(aName + " -> " + "Index: " + i + " Error: " + e.Message);
                    }
                }
                onMsg("End " + aName);
            },name);
        }

        public static void Run()
        {
            taskA.Start();
            taskB.Start();
        }
    }
}
    void HandleOnMessage(string msg)
    {
        UIApplication.SharedApplication.InvokeOnMainThread(() => Console.WriteLine(msg));
    }

    void DoIt()
    {
        var platform = new SQLite.Net.Platform.XamarinIOS.SQLitePlatformIOS();
        platform.SQLiteApi.Config(ConfigOption.Serialized);

        var path = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
        path = Path.Combine(path, "test.db");

        TestTask.Init(platform, path, HandleOnMessage);
        TestTask.Run();
    }
  • 我在Android模拟器和Android设备中遇到了同样的问题
  • 我正在使用VisualStudioforMac7.4.3(Build10)
  • 我正在用iOS 11.3在iPhoneX模拟器上调试

    • 我自己解决了

      这是“SQLite.Net PCL”Nuget包中的一个问题

      在连接处使用“sqlite net pcl”代替读|写|全互斥标志。
      FullMutex标志正在强制序列化模式。

      我已经更新了我的问题,出现了完全异常。您好,您能否提供一些关于如何在连接上设置标志的代码示例?谢谢