由于并行的地理编码api超过QUERY LIMIT

时间:2018-04-18 15:10:41

标签: c# google-maps task-parallel-library

我有一个要求,我必须在服务器端使用Geocode API验证很多地址(大约5000)。因此我决定使用parallel来一次向API发送多个请求(为了减少执行时间) 这是我的代码

    //Address object
    public class AddressModel 
        {
            public int AddressID { get; set; }
            public string AddressLineOne { get; set; }
            public string AddressLineTwo { get; set; }
            public string City { get; set; }
            public string State { get; set; }
            public string ZipCode { get; set; }
        }

    //Main code starts here
    List<AddressModel> Addresses = GetAddressesFromFile();  //This will add around 5k addresses to the list
    Parallel.For(0, Addresses.Count, i =>
                    {
                        System.Net.WebResponse response = ResolveAddressFromGoogle(Addresses[i]);
                        //Process google response 
                    });


    public System.Net.WebResponse ResolveAddressFromGoogle(AddressModel address)
            {
                System.Net.WebResponse response = null;
                try
                {
            string urlGoogleApi = "https://maps.googleapis.com/maps/api/geocode/xml?address={0}&sensor=false&key=mykey&components=postal_code:{1}";
                    urlGoogleApi = string.Format(urlGoogleApi, address.AddressLineOne, address.Zip.ZipCode);
                    System.Net.WebRequest req = System.Net.WebRequest.Create(urlGoogleApi );
                    req.Method = "GET";
                    response = req.GetResponse();
                }
                catch (Exception ex)
                {
                    response = null;
                }
                return response;
            }

但问题是每秒有超过50个请求被发送到API,因为我得到了很多地址的超量查询限制响应。 有没有办法将请求限制为每秒50个?

我尝试了一种方法,如果响应包含over_query_limit字符串,我尝试将任务延迟1秒,就像这样

Parallel.For(0, Addresses.Count, i =>
                    {
                        label:
                        System.Net.WebResponse response = ResolveAddressFromGoogle(Addresses[i]);
                        //If response contain over_query_limit
                        Task.delay(1000);
                        goto label;
                        //else process google response normally
                    });

但它似乎不起作用。任何帮助将不胜感激

1 个答案:

答案 0 :(得分:0)

尝试在ParallelOptions中指定MaxDegreeOfParallelism并等待来自API的响应。我不确定它会给你50个连接,这只是你指定50时允许给出的最大值。我用5来说明它有效。给定20个元素,每个元素的最大速度为1秒,最大为5个并发,完成for循环至少需要4秒。

        List<string> addresses = new List<string>();
        for (int i = 0; i < 20; i++)
        {
            addresses.Add(string.Empty);
        }

        Parallel.For(0, 
                     addresses.Count, 
                     new ParallelOptions{MaxDegreeOfParallelism = 5}, 
                     i =>
                    {
                        Console.WriteLine(DateTime.UtcNow.ToString("HH:mm:ss"));
                        Task.Delay(1000).Wait(); // simulating a long running event
                    }
        );