2017-08-26 54 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

相關問題