Автономная синхронизация Xamarin с AzureMobileServices: начальная автономная загрузка невероятно медленная - PullRequest
0 голосов
/ 31 мая 2018

Я успешно использую мобильные службы Azure и формы Xamarin для выполнения операций CRUD над базой данных SQL, размещенной в Azure.Часть автономной синхронизации хранит данные в базе данных SQLite на телефоне.На этом пути было несколько препятствий, чтобы заставить его работать так же гладко, как сейчас, но это остается последним препятствием.

Проблема

Когда устройство не подключено (проверено в режиме «В самолете» на различных физических и эмулируемых устройствах) - при первом обращении к любым автономным данным требуется очень долгое время, чтобы вернуть что-либо.Это тот случай, если данные существуют в БД SQLite или нет.

Не выдается ни одно исключение, или что-либо, что я вижу напечатанным в журналах, который указывает на возможную задержку.

Чтобы дать представление, PullAsync() на 20 строках может занять5 секунд в режиме онлайн, и эти данные сохраняются в БД SQLite.После перевода устройства в автономный режим эта же операция может занять до 60 секунд.Эти цифры совершенно произвольны, но задержка заметно слишком велика.

Чтобы добавить к этому, эта длинная загрузка происходит только в самый первый раз , вызывается любой метод автономной синхронизации.После этого каждый метод почти мгновенный, как я и ожидал, - но почему бы не в первый раз?

Ожидаемый результат

Я ожидал бы этого, потому что данные хранятся на устройстве.уже, и никакое интернет-соединение не может быть обнаружено, оно должно вернуть данные почти мгновенно.

Код

Класс синхронизации

The *Метод 1029 * GetPolicies() - это место задержки. Это образец одного из компонентов.Все остальные компоненты имеют одинаковый формат, но разные данные.

    IMobileServiceSyncTable<policy_procedure> policyTable = SyncController.policyTable;

    public async Task<List<policy_procedure>> GetPolicies(string companyId)
    {
        //SemaphoreSlim
        await SyncController.dbOperation.WaitAsync();
        try
        {
            await SyncController.Initialize();
            await policyTable.PullAsync("policy_procedure", policyTable.Where(p => p.fk_company_id == companyId).Where(p=> p.signature!=null || p.signature!=""));
            return await policyTable.ToListAsync();
        }
        catch (Exception ex)
        {
            //For some reason, when this method is called and the device is offline, it will fall into this catch block. 
            //I assume this is standard for offline sync, as it's trying to do a pull with no connection, causing it to fail. 
            //Through using breakpoints, the delay occurs even before it reaches this catch statement.
            Console.WriteLine(ex);
            return await policyTable.ToListAsync();
        }
        finally
        {
            SyncController.dbOperation.Release();
        }
    }

Контроллер синхронизации

    public static SemaphoreSlim dbOperation = new SemaphoreSlim(1, 1);
    public static MobileServiceClient client;
    public static MobileServiceSQLiteStore store;
    public static async Task Initialize()
    {
        try
        {
            //This line is not standard for Offline Sync.
            //The plugin returns true or false for the devices current connectivity. 
            //It's my attempt to see if there is a connection, to eliminate the load time.
            //This does immediately take it back to the try statement in GetPolicies
            if (!CrossConnectivity.Current.IsConnected)
                return;
            if (client ? .SyncContext ? .IsInitialized ? ? false)
                return;
            client = new MobileServiceClient(AppSettings.azureUrl);
            var path = "local.db"; //Normally uses company ID, 
            path = Path.Combine(MobileServiceClient.DefaultDatabasePath, path);
            store = new MobileServiceSQLiteStore(path);
            /************************/
            #
            region Table Definitions in local SQLite DB
            //Define all the tables in the sqlite db
            ..
            store.DefineTable < policy_procedure > ();
                ..#endregion
            await client.SyncContext.InitializeAsync(store);
            /************/
            #
            region Offline Sync Tables
                ..
            policyTable = client.GetSyncTable < policy_procedure > ();
                ..#endregion
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex)
        }
    }

Что я пробовал

Ну, я не слишкомЯ уверен, что это даже является причиной, поэтому большинство моих попыток были связаны с принудительным созданием исключения до того, как произойдет это время ожидания, чтобы оно могло выпасть из GetPolicies try-catch, так как время ожидания, по-видимому, на PullAsync.

Моя последняя попытка сделать это прокомментирована в приведенном выше коде (SyncController), где я использую подключаемый модуль для подключения Джеймса Монтемагно * для определения сетевого подключения телефона. (я проверял это отдельно, и это работает правильно без задержки.)

1 Ответ

0 голосов
/ 06 июня 2018

Короче говоря, вы не хотите вызывать PullAsync в своем методе GetPolicies, если ваше устройство находится в автономном режиме.Например, вы можете сделать

    try
    {
        await SyncController.Initialize();
        if (CrossConnectivity.Current.IsConnected)
        {
            await policyTable.PullAsync("policy_procedure", policyTable.Where(p => p.fk_company_id == companyId).Where(p=> p.signature!=null || p.signature!=""));
        }
        return await policyTable.ToListAsync();
    }

, но вы также захотите обработать случай, когда приложение запускается впервые, и поэтому у вас еще нет записей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...