Я успешно использую мобильные службы 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
), где я использую подключаемый модуль для подключения Джеймса Монтемагно * для определения сетевого подключения телефона. (я проверял это отдельно, и это работает правильно без задержки.)