UWP:如何通过异步调用优化 WCF WebServices 和 SQLite 之间的同步

问题描述 投票:0回答:1

我必须在 SQLite 数据库中同步来自 WCF WebServices 的数据。 此同步代表了十几个 Web 服务,可以将其“分组”为 4 类:

  • 用户的”权利
  • Forms”数据,可以从两侧(用户/服务器)更新
  • 服务器”数据,仅从服务器更新
  • Views”数据,将服务器的视图复制到本地

对WebService的每次调用都是通过HttpClient完成的:

response = await client.PostAsync(webServiceName, content);

每个 WebService 都有自己的 async 方法,其中 WebService 响应是 反序列化

public static async Task<string> PushForm(List<KeyValuePair<string, string>> parameters)
{
    var response = await JsonParser.GetJsonFromUrl(WebServiceName.PushForm.Value, parameters);
    Forms forms = new Forms();
    try
    {
        forms = JsonConvert.DeserializeObject<Forms>(response);
        return response;
    }
    catch (Exception e)
    {
        throw new Exception(e.Message);
    }
}

然后我有一个 SynchronizationService 类,我在其中按类别重新组合对 WebServices 的调用:

public async Task<bool> SynchronizeServerData()
{
    bool result = false;
    try
     {
        result = true;
        List<Table1> tables1 = await WebServices.GetListTable1(null);
        if (tables1 != null)
        {
            ServiceLocator.Current.GetInstance<IRepository>().DeleteAll<Table1>(true);
            ServiceLocator.Current.GetInstance<IRepository>().AddAll<Table1>(tables1);
        }
        List<Table2> tables2 = await WebServices.GetListTable2(null);
        if (tables2 != null)
        {
            ServiceLocator.Current.GetInstance<IRepository>().DeleteAll<Table2>(true);
            ServiceLocator.Current.GetInstance<IRepository>().AddAll<Table2>(tables2);
        }
        List<Table3> tables3 = await WebServices.GetListTable3(null);
        if (tables3 != null)
        {
            ServiceLocator.Current.GetInstance<IRepository>().DeleteAll<Table3>(true);
            ServiceLocator.Current.GetInstance<IRepository>().AddAll<Table3>(tables3);
        }
        ...
    }
    catch (Exception e)
    {
        result = false;
    }
    return result;
}

最后,在 main ViewModel 中,我调用以下每个方法:

public async void SynchronizeData(bool firstSync)
{
    IsBusy = true;
    var resUsers = await _synchronisation.SynchronizeUsersRights();
    var resServer = await  _synchronisation.SynchronizeServerData();
    var resForm = await _synchronisation.SynchronizeForms();
    var resViews = await _synchronisation.SynchronizeViews();
    IsBusy = false;
}

但由于使用了“await”,性能不佳。

=> 我想知道是否有一种简单的方法可以“并行化”调用以优化性能?或者是否可以将数据恢复与 SQLite 更新分开?

c# wcf asynchronous synchronization async-await
1个回答
1
投票

从表面上看,似乎有机会同时运行几件事,例如在

SynchronizeData
中,你可以这样做:

{
    IsBusy = true;
    Task resUsersTask = _synchronisation.SynchronizeUsersRights();
    Task resServerTask = _synchronisation.SynchronizeServerData();
    Task resFormTask = _synchronisation.SynchronizeForms();
    Task resViewsTask = _synchronisation.SynchronizeViews();
    await Task.WhenAll(resUsersTask, resServerTask, resFormTask, resViewsTask);
    var resUsers = resUsersTask.Result;
    var resServer = resServerTask.Result;
    var resForm = resFormsTask.Result;
    var resViews = resViewsTask.Result;       
    IsBusy = false;
}

...这将允许这 4 个任务同时运行。

您可以在

SynchronizeServerData
中执行相同操作;例如:

result = true;
Task tables1Task = WebServices.GetListTable1(null);
Task tables2Task = WebServices.GetListTable2(null);
Task tables3Task = WebServices.GetListTable3(null);

List<Table1> tables1 = await tables1Task;
// ...

List<Table2> tables2 = await tables2Task;
// ...

List<Table3> tables3 = await tables3Task;
// ...

这也将允许 3 个任务同时运行。

你实际上从中获得多少可能取决于诸如 SQLite 是否允许你执行多个并发请求之类的事情 - 我不知道这个问题的答案。

其他一些评论:

public async void SynchronizeData(bool firstSync)

async void
几乎总是不正确的,除了事件处理程序和罕见的即发即弃方法,并且通常
async Task
就是您想要的。 搜索 SO 寻找许多关于原因的好答案。

最后,您真正应该做的是分析代码以了解真正的瓶颈在哪里。

© www.soinside.com 2019 - 2024. All rights reserved.