在xamarin项目中使用MobileServiceClient和MobileServiceSQLiteStore'数据库被锁定'

Rod*_*ney 6 sqlite azure-mobile-services xamarin.forms

我对移动和异步数据访问相对较新,我正在尝试从VS2017中的Xamarin首发"跨平台"模板构建业务线应用程序.似乎当我经常进行数据库操作时,我得到'数据库被锁定'(大多数问题涉及自己的sqlite实现).我添加了非常详细的日志记录(我必须支持非技术端移动用户).

我更改为(如其他答案中所建议的)用于数据库访问的单例模型,该模型在调用table.ReadAsync时生成不可跟踪(意味着没有异常被捕获且没有xamarin日志条目)异常(见下文).

作为第二个问题,花了这么多时间在这上面并遇到了许多不同的障碍(毫无疑问是我自己制作的)我想知道我是否没有遵循一些潜规则的移动开发,例如"只有一个异步对象"每页读取并设计100%异步的UI".我想做太多吗?这是我目前的"单例"数据访问类:

public static class MainDataStore
{
    private static ReaderWriterLockSlim ReadLock = new ReaderWriterLockSlim();

    public static bool IsInitialized { get; set; }
    public static MobileServiceClient MobileService { get; set; }
    public static bool UseAuthentication = true;
    public static IMobileServiceSyncTable<User> UserTable;
    public static IMobileServiceSyncTable<Showroom> ShowroomTable;

    public static IEnumerable<User> Users { get; set; } //= new ObservableRangeCollection<User>();
    public static IEnumerable<Showroom> Showrooms { get; set; }

    public static void InitializeAsync()
    {
        try
        {

            if (IsInitialized)
                return;

            Logging.D("Starting to initialize main store.");

            AuthenticationHandler handler = null;

            handler = new AuthenticationHandler();

            MobileService = new MobileServiceClient(App.AzureMobileAppUrl, handler)
            {
                SerializerSettings = new MobileServiceJsonSerializerSettings
                {
                    CamelCasePropertyNames = true
                }
            };

            var store = new MobileServiceSQLiteStore(Settings.DatabaseName);

            store.DefineTable<User>();
            store.DefineTable<Showroom>();

            MobileService.SyncContext.InitializeAsync(store, new MobileServiceSyncHandler());

            UserTable = MobileService.GetSyncTable<User>();
            ShowroomTable = MobileService.GetSyncTable<Showroom>();

            Logging.D("Finished initializing main store.");

            IsInitialized = true;
        }
        catch (Exception ex)
        {
            Logging.E(ex); // Debug.WriteLine("EXCEPTION: " + ex.Message + ". Stack: " + ex.StackTrace);
        }
    }

    public static async void Load(ECarnavalObjectType type)
    {
        Logging.D("Reading lock entering. Read count: " + ReadLock.CurrentReadCount.ToString());

        // ReadLock.EnterReadLock();

        switch (type)
        {
            case ECarnavalObjectType.Users:
                await GetUsersAsync();
                Users = await UserTable.ToEnumerableAsync();
                break;
            case ECarnavalObjectType.Showrooms:
                await GetShowroomsAsync();
                Showrooms = await ShowroomTable.ToEnumerableAsync();
                break;
        }

        //  ReadLock.ExitReadLock();
    }
    public static async Task GetUsersAsync()
    {
        if (CrossConnectivity.Current.IsConnected)
        {
            try
            {
               // await UserTable.ReadAsync<User>(UserTable.CreateQuery());
await UserTable.PullAsync($"all{typeof(User).Name}", UserTable.CreateQuery());
            }
            catch (Exception ex)
            {

            }
        }
    }
    public static async Task GetShowroomsAsync()
    {
        await ShowroomTable.ReadAsync<Showroom>(ShowroomTable.CreateQuery());
    }
}
Run Code Online (Sandbox Code Playgroud)

Adr*_*all 0

在您的代码中,您没有等待 InitializeAsync(),这意味着当您去同步数据库时,数据库可能仍处于锁定状态并正在设置中。

将代码安排在单例中,然后调用每个方法(读取/列表/等)await InitializeAsync()来初始化数据库。尽早返回InitializeAsync()方法(您已经为此提供了一些很好的代码)。

有关更多信息,请参阅我的书:https ://adrianhall.github.io/develop-mobile-apps-with-csharp-and-azure/chapter3/client/