Xamarin形成了Azure移动应用的缓慢同步

Arn*_*aud 5 offline-caching xamarin.android azure-mobile-services xamarin.forms

我正在将Azure移动应用程序与Xamarin.Forms一起使用以创建具有脱机功能的移动应用程序。

我的解决方案基于https://adrianhall.github.io/develop-mobile-apps-with-csharp-and-azure/chapter3/client/

这是我用于离线同步的代码:

public class AzureDataSource
    {
        private async Task InitializeAsync()
        {
            // Short circuit - local database is already initialized
            if (client.SyncContext.IsInitialized)
            {
                return;
            }

            // Define the database schema
            store.DefineTable<ArrayElement>();
            store.DefineTable<InputAnswer>();
            //Same thing with 16 others table
            ...

            // Actually create the store and update the schema
            await client.SyncContext.InitializeAsync(store, new MobileServiceSyncHandler());
        }

        public async Task SyncOfflineCacheAsync()
        {
            await InitializeAsync();

            //Check if authenticated
            if (client.CurrentUser != null)
            {
                // Push the Operations Queue to the mobile backend
                await client.SyncContext.PushAsync();

                // Pull each sync table
                var arrayTable = await GetTableAsync<ArrayElement>();
                await arrayTable.PullAsync();

                var inputAnswerInstanceTable = await GetTableAsync<InputAnswer>();
                await inputAnswerInstanceTable.PullAsync();

                //Same thing with 16 others table
                ...
            }
        }

        public async Task<IGenericTable<T>> GetTableAsync<T>() where T : TableData
        {
            await InitializeAsync();
            return new AzureCloudTable<T>(client);
        }
    }
    public class AzureCloudTable<T>
    {
        public AzureCloudTable(MobileServiceClient client)
        {
            this.client = client;
            this.table = client.GetSyncTable<T>();
        }

        public async Task PullAsync()
        {
            //Query name used for incremental pull
            string queryName = $"incsync_{typeof(T).Name}";

            await table.PullAsync(queryName, table.CreateQuery());
        }
    }
Run Code Online (Sandbox Code Playgroud)

问题在于,即使没有什么要拉的内容,同步也要花费很多时间(在Android设备上为8-9秒,而拉取整个数据库则为25秒以上)。

我查看了Fiddler,发现移动应用后端需要多少时间才能响应,每个请求大约需要50毫秒,因此问题似乎并非出在这里。

有人遇到同样的麻烦吗?我做错了什么或改善同步性能的提示吗?

Bej*_*asc 0

我们的特殊问题与我们的数据库迁移有关。数据库中的每一行都有相同的updatedAt值。我们运行一个 SQL 脚本来修改它们,以便它们都是唯一的。

此修复实际上是针对我们遇到的其他一些问题,即并非所有行都由于某种未知原因而返回,但我们也看到了速度的显着提高。


另外,另一个奇怪的修复方法可以改善加载时间,如下所示。

在我们第一次提取所有数据后(可以理解,这需要一些时间) - 我们对返回的其中一行进行了操作UpdateAsync()之后我们没有推送它。

我们已经了解到,离线同步的工作方式是,它将提取日期比最近更新日期更新的任何内容。与此相关的速度略有提高。


最后,我们为提高速度所做的最后一件事是,如果数据已在视图中缓存了副本,则不再获取数据。但这可能不适用于您的用例。

public List<Foo> fooList = new List<Foo>

public void DisplayAllFoo()
{
    if(fooList.Count == 0)
        fooList = await SyncClass.GetAllFoo();

    foreach(var foo in fooList)
    {
        Console.WriteLine(foo.bar);
    }
}
Run Code Online (Sandbox Code Playgroud)

2019 年 3 月 20 日编辑:有了这些改进,我们仍然看到同步操作非常慢,使用方式与 OP 中提到的相同,还包括我的答案中列出的改进。

我鼓励所有人分享他们关于如何提高速度的解决方案或想法。