2017-08-26 98 views
0

我们有一个地址数据表,我试图对地理编码进行测试。为什么谷歌地理编码需要花费这么长时间使用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()); 
+0

看起来您似乎一次启动8,000个Web请求? –

回答

1

几点建议:
1)增加ServicePointManager.DefaultConnectionLimit默认为2个并行连接

2)可以具有如果所有结果高线程争正在锁定桌子。如果您没有内存限制,请考虑将结果添加到ConcurrentDictionary

3)将请求分成批次以避免耗尽您打开的连接池。

4)小代码注释:
- 如果使用默认设置,而不是使用Task.Factory.StartNew
Task.Run - i++有竞争条件和可能不准确。您可以使用Interlocked.Increment代替

+0

谢谢@Itsik!关于(1)和(3),关于如何计算健康连接限制和批量大小的任何提示? –

+0

以上哪个解决了你的问题? #1:您可以通过查看“ServicePoint.CurrentConnections”来监视多少个打开的连接。这有一个内部锁,所以不要将其作为上述操作的一部分运行。您可以开始增加,直到没有任何性能增益,只需考虑: a)如果这是从服务器运行,您有出站端口限制 b)谷歌可能会阻止你。 我会根据#1调整#3 – Itsik

相关问题