我有一个要求,我必须在服务器端使用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
});
但它似乎不起作用。任何帮助将不胜感激
答案 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
}
);