为什么谷歌地理编码需要花费这么长时间使用DownloadStringAsync(Uri,Object)C#
我们有一个地址数据表,我试图对地理编码进行测试。为什么谷歌地理编码需要花费这么长时间使用DownloadStringAsync(Uri,Object)C#
然后我们遍历数据表行,使用WebClient.downloadStringAsync(Uri,Object)将api请求发送到Google Geocoding,并对数据表进行所述更新。
所有线程完成后,我们需要更新数据库。
为此,我们使用Task.Factory.StartNew函数并跟踪它们以等待所有任务完成。
我们在8000多个地址的超过10分钟内看到了这一点。
这是正常的还是有更好的方法呢?
任何建议表示赞赏。
下调代码是下面供参考:
DataTable dataTable = new DataTable();
String url = "https://maps.googleapis.com/maps/api/geocode/json?address={0}&key={1}";
List<Task> tasks = new List<Task>();
int i = 0;
foreach (DataRow row in dataTable.Rows) //8000 + rows
{
Uri uriWithAddress = new Uri(String.Format(url, new[] {
"full_address",
"apiKey"
}));
tasks.Add(Task.Factory.StartNew(() => {
using (System.Net.WebClient client = new System.Net.WebClient())
{
client.DownloadStringCompleted += (o, a) =>
{
//when finished... do some work like lock datatable
//and change some values etc
};
client.DownloadStringAsync(uriWithAddress, i);
i++;
}
}));
Task.WaitAll(tasks.ToArray());
几点建议:
1)增加ServicePointManager.DefaultConnectionLimit
默认为2个并行连接
2)可以具有如果所有结果高线程争正在锁定桌子。如果您没有内存限制,请考虑将结果添加到ConcurrentDictionary
3)将请求分成批次以避免耗尽您打开的连接池。
4)小代码注释:
- 如果使用默认设置,而不是使用Task.Factory.StartNew
Task.Run - i++
有竞争条件和可能不准确。您可以使用Interlocked.Increment
代替
谢谢@Itsik!关于(1)和(3),关于如何计算健康连接限制和批量大小的任何提示? –
以上哪个解决了你的问题? #1:您可以通过查看“ServicePoint.CurrentConnections”来监视多少个打开的连接。这有一个内部锁,所以不要将其作为上述操作的一部分运行。您可以开始增加,直到没有任何性能增益,只需考虑: a)如果这是从服务器运行,您有出站端口限制 b)谷歌可能会阻止你。 我会根据#1调整#3 – Itsik
看起来您似乎一次启动8,000个Web请求? –