【问题标题】:matching async api call results to requests将异步 api 调用结果与请求匹配
【发布时间】:2020-11-14 01:30:52
【问题描述】:

我正在尝试使用 httpclient 实现异步 api 调用。我已经使用带有我的密钥对值的字典进行调用,以将其写回数据库,从而将其绑定回正确的源记录。

我不知道如何将调用与原始更新请求相关联。

这是工作的重点:

var s_urlList = xmltogo.AsEnumerable().ToDictionary<DataRow, int, string>(row => Convert.ToInt32(row.Field<string>(0)), row => row.Field<string>(1));


                    IEnumerable<Task<string>> downloadTasksQuery =
                    from url in s_urlList.Values
                    select CallAPI(url);

                    List<Task<string>> downloadTasks = downloadTasksQuery.ToList();

                    while (downloadTasks.Any())
                    {
                       Task<string> finishedTask = await Task.WhenAny(downloadTasks);

                        downloadTasks.Remove(finishedTask);

                        string XMLResult = finishedTask.Result.ToString();

                    }

任何帮助表示赞赏。

【问题讨论】:

  • 为什么不直接使用await Task.WhenAll(downloadTasksQuery);,然后遍历每个任务来检查结果。
  • 我想在每次通话完成后进行工作。将会有数百个。仍然如何将 s-urlList.Key 与完成的任务联系起来?。

标签: c# async-await httpclient


【解决方案1】:

我需要将密钥和 xml 作为 2 个参数传递给我的方法,然后将其返回:

Dictionary<int, string> s_urlList = xmltogo.AsEnumerable().ToDictionary<DataRow, int, string>(row => Convert.ToInt32(row.Field<string>(0)), row => row.Field<string>(1));


                    IEnumerable<Task<(int,string)>> downloadTasksQuery =
                    from url in s_urlList
                    select CallAPI(url.Key, url.Value);

                    List<Task<(int,string)>> downloadTasks = downloadTasksQuery.ToList();

                    while (downloadTasks.Any())
                    {
                       Task<(int, string)> finishedTask = await Task.WhenAny(downloadTasks);


                        downloadTasks.Remove(finishedTask);

                        string XMLResult = finishedTask.Result.Item2.ToString();
                        int key = finishedTask.Result.Item1;
                        Console.WriteLine("key: " + key.ToString() + "XML: " + XMLResult);
                    }

【讨论】:

    【解决方案2】:
     var s_urlList = xmltogo.AsEnumerable().ToDictionary<DataRow, int, string>(row => Convert.ToInt32(row.Field<string>(0)), row => row.Field<string>(1));
    
            List<Tuple<string, string>> xmlResults =new  List<Tuple<string,string>>() 
            IEnumerable<System.Threading.Tasks.Task<string>> downloadTasksQuery =
            from url in s_urlList.Values
            select CallAPI(url).ContinueWith(x=> xmlResults.Add(url, x.Result));
    
            List<Task<string>> downloadTasks = downloadTasksQuery.ToList();
    
           await Task.WhenAll(downloadTasks);
            foreach (var xmlResult in xmlResults)
            {
                string url = xmlResult.Item1,
                       XMLResult = xmlResult.Item2;
                // use your result here
            }
    

    【讨论】:

    • 是的,这就是结果操作应该在的地方。但是我如何将结果与请求 s_urlList.Key 相关联以更新我的数据库中的正确记录。
    • 您可以在 continue with 或 in for each 中进行操作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-05
    • 2018-12-15
    • 1970-01-01
    • 1970-01-01
    • 2014-11-07
    • 1970-01-01
    相关资源
    最近更新 更多