我成功使用Azure Mobile Services和Xamarin Forms在Azure托管的SQL数据库上执行CRUD操作。脱机同步部分将数据存储在手机上的SQLite数据库中。为了让它像我们现在一样平稳地工作,一直有一些障碍,但这仍然是最后一道障碍。
当设备没有连接时(在各种物理和仿真设备上使用飞行模式进行测试) - 第一次访问任何离线数据时,非常很长时间什么都归还如果数据存在于SQLite DB中,则会出现这种情况。
没有抛出任何异常,或者我可以看到打印到日志中的任何内容,表明延迟可能是什么。
要提出一个想法,在线时,20行上的PullAsync()
可能需要5秒,并且该数据将存储到SQLite DB中。将设备置于离线模式后,相同的操作可能需要60秒。这些数字非常随意,但延迟时间明显太长。
要添加此功能,此长时间加载仅发生第一次调用任何脱机同步方法。在那之后,每种方法都接近即时,正如我所期望的那样 - 但为什么不是第一次?
我希望由于数据已存储在设备上,并且无法检测到互联网连接,因此它应该几乎立即返回数据。
同步课程
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
)中得到了评论,我使用James Montemagno的Connectivity Plugin来检测手机的网络连接。 (我已经单独测试了这个,这可以毫不拖延地正常工作。)
答案 0 :(得分:1)
简短的说法是,如果您的设备处于离线状态,则不希望在GetPolicies方法中调用PullAsync。例如,你可以做
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();
}
但你也想要处理这是第一次运行应用程序的情况,因此你还没有任何记录。