首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >xamarin形成蓝色移动应用程序慢同步

xamarin形成蓝色移动应用程序慢同步
EN

Stack Overflow用户
提问于 2018-01-15 09:12:27
回答 2查看 827关注 0票数 6

我正在使用Azure与Xamarin.Forms一起创建一个离线的移动应用程序。

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

下面是用于脱机同步的代码:

代码语言:javascript
复制
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());
        }
    }

问题是,即使没有任何东西可做,同步也要花费很长时间( Android设备上需要8-9秒,整个数据库需要超过25秒)。

我查看了费德勒,以找出移动应用程序BackEnd响应所需的时间,每个请求大约需要50毫秒,所以问题似乎不是从这里来的。

有人也有同样的麻烦吗?有什么地方是我做错或提示,以提高我的同步性能?

EN

回答 2

Stack Overflow用户

发布于 2018-05-31 01:43:25

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

这个修复实际上是因为一些其他的问题,在这个问题上,并不是所有的行都因为某种未知的原因而被返回,但是我们也看到了一个很大的速度改进。

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

在我们第一次提取所有数据之后(这是可以理解的,需要一些时间)--我们在返回的一个行上做了一个UpdateAsync(),之后我们没有按它。

我们已经了解到离线同步的工作方式是,它将提取任何有日期更新的,而不是最近更新的。与此相关的是一小部分速度的提高。

最后,我们为提高速度所做的最后一件事是,如果数据已经在视图中缓存了一个副本,就不会再次获取数据。不过,这对您的用例可能不起作用。

代码语言:javascript
复制
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);
    }
}

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

我鼓励大家就如何提高这一速度分享他们的解决办法或想法。

票数 0
EN

Stack Overflow用户

发布于 2020-04-05 02:12:34

拉()慢的原因之一是(10)行得到相同的UpdatedAt值。当您同时更新行时会发生这种情况,例如运行SQL命令。

克服这种情况的一种方法是修改表上的默认触发器。为了确保每一行都得到一个唯一的UpdateAt,我们执行了如下操作:

代码语言:javascript
复制
ALTER TRIGGER [dbo].[TR_dbo_Items_InsertUpdateDelete] ON [dbo].[TableName]
AFTER INSERT, UPDATE, DELETE
AS
     BEGIN

         DECLARE @InsertedAndDeleted TABLE
         (
              Id        NVARCHAR(128) 
         );
         DECLARE @Count     INT, 
                 @Id        NVARCHAR(128);

         INSERT INTO @InsertedAndDeleted
                SELECT Id
                FROM inserted;
         INSERT INTO @InsertedAndDeleted
                SELECT Id
                FROM deleted
                WHERE Id NOT IN
                (
                    SELECT Id
                    FROM @InsertedAndDeleted
                );

         --select * from @InsertedAndDeleted;
         SELECT @Count = Count(*)
         FROM @InsertedAndDeleted;

         -- ************************ UpdatedAt ************************
         -- while loop
         WHILE @Count > 0
         BEGIN
             -- selecting
             SELECT TOP (1) @Id = Id
             FROM @InsertedAndDeleted;

             -- updating
             UPDATE [dbo].[TableName]
                    SET UpdatedAt = Convert(DATETIMEOFFSET, DateAdd(MILLISECOND, @Count, SysUtcDateTime()))
             WHERE Id = @Id;

             -- deleting
             DELETE FROM @InsertedAndDeleted
             WHERE id = @Id;

             -- counter
             SET @Count = @Count - 1;
         END;
     END;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48259872

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档