加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 使用多个任务从大型对齐中检索所有记录

发布时间:2020-12-15 03:53:04 所属栏目:百科 来源:网络整理
导读:我正在处理调用外部服务的应用程序,并且必须将外部集合的所有条目添加到本地集合中.目前的问题是外部收藏可能会超过1000条记录,但返回的搜索结果只能包含最多二十项. 为了速度,我想使用一组任务将是前进的道路,所以我想出了下面的代码: int totalCount = re
我正在处理调用外部服务的应用程序,并且必须将外部集合的所有条目添加到本地集合中.目前的问题是外部收藏可能会超过1000条记录,但返回的搜索结果只能包含最多二十项.

为了速度,我想使用一组任务将是前进的道路,所以我想出了下面的代码:

int totalCount = returnedCol.total_count;
        while (totalCount > myDict.Count)
        {
            int numberOfTasks = // logic to calculate how many tasks to run

            List<Task> taskList = new List<Task>();

            for (int i = 1; i <= numberOfTasks; i++)
            {
                Interlocked.Add(ref pageNumber,pageSize);

                Task<SearchResponse> testTask = Task.Run(() =>
                {
                    return ExternalCall.GetData(pageNumber,pageSize);
                });

                Thread.Sleep(100);

                taskList.Add(testTask);
                testTask.ContinueWith(o =>
                {
                    foreach (ExternalDataRecord dataiwant in testTask.Result.dataiwant)
                    {
                        if (!myDict.ContainsKey(dataiwant.id))
                            myDict.GetOrAdd(dataiwant.id,dataiwant);
                    }
                });
            }
            Task.WaitAll(taskList.ToArray());
        }

但是,这并不能产生所有结果. pageNumber变量每次正确递增,但似乎并不是所有的任务结果都被分析(因为较小数据集上的单个线程上的相同逻辑返回所有预期结果).此外,我已经尝试在链中声明单个任务(而不是循环),并且返回测试数据.看来,我传入Thread.Sleep()的值越高,结果将被添加到本地集合中(但这不是理想的,因为这意味着该过程需要更长时间!)

目前在600个记录的样本中,只有约150-200个添加到myDict集合中.我错过了什么吗?

解决方法

你错过了ContinueWith()导致另一个任务,而不是添加你的taskList的事实.

更好的方法是使用.NET 4.5之后的async / await.它为解决方案提供了一种较不重要的方法.

您将更改算法更像这样:

public async Task Process()
{
    int totalCount = returnedCol.total_count;

    while (totalCount > myDict.Count)
    {
        int numberOfTasks = // logic to calculate how many tasks to run

        List<Task> taskList = new List<Task>();

        for (int i = 1; i <= numberOfTasks; i++)
        {
            Interlocked.Add(ref pageNumber,pageSize);

            taskList.Add(ProcessPage(pageNumber,pageSize));
        }

        await Task.WhenAll(taskList.ToArray());
    }
 }

 private async Task ProcessPage(int pageNumber,int pageSize)
 {
       SearchResponse result = await Task.Run(() => 
           ExternalCall.GetData(pageNumber,pageSize)).ConfigureAwait(false);

       foreach (ExternalDataRecord dataiwant in result.dataiwant)
       {
           myDict.GetOrAdd(dataiwant.id,dataiwant);
       }
 }

async关键字告诉编译器稍后会有一个等待.等待基本上处理您的ContinueWith调用的细节.如果您真的希望ExternalCall发生在另一个任务中,那么您只需等待该调用的结果.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读