我们有一个包含地址的数据表,我正在尝试对其进行地理编码。
然后,我们循环浏览数据表行,使用 WebClient.downloadStringAsync(Uri, Object( 向 Google 地理编码发送 api 请求,并对数据表进行描述的更新。
完成所有线程后,我们需要对数据库进行更新。
为此,我们使用Task.Factory.StartNew Function并跟踪它们以等待所有任务完成。
我们在 10 分钟内看到 8000 个地址的完成。
这是正常的还是有更好的方法?
任何建议不胜感激。
精简的代码如下,供参考:
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(增加默认为2个并发连接的ServicePointManager.DefaultConnectionLimit
2( 如果所有结果都锁定了表,则可能会有很高的线程争用。如果没有内存约束,请考虑将结果添加到ConcurrentDictionary
3( 将请求分成批处理,以避免耗尽打开的连接池。
4( 小代码注释:-
如果使用默认设置,请使用 Task.Run 而不是 Task.Factory.StartNew
-i++
存在争用条件,可能不准确。您可以改用Interlocked.Increment