我在ssis包中有一个c#脚本任务,旨在通过我公司的专有系统对数据进行地理编码。它目前的工作方式如下:
1)拉取地址查询并输入数据表 2)遍历该表和Foreach行,构建请求,发送请求,等待响应,然后插回数据库。
问题是每次调用都需要永远返回,因为在外出并在api端获取新地址之前,它会检查当前数据库(字符串匹配)以确保该地址尚不存在。如果不存在,那就出去从谷歌这样的服务中获取新数据。
因为我一次只进行一次,所以当我返回将其插入数据库时,可以很容易地将ID字段与记录保持在一起。
现在出现了问题......我被告知将其配置为多线程或异步。这是我在这里阅读的关于这个主题的页面: ASP.NET Multithreading Web Requests
var urls = new List<string>();
var results = new ConcurrentBag<OccupationSearch>();
Parallel.ForEach(urls, url =>
{
WebRequest request = WebRequest.Create(requestUrl);
string response = new StreamReader(request.GetResponse().GetResponseStream()).ReadToEnd();
var result = JsonSerializer().Deserialize<OccupationSearch>(new JsonTextReader(new StringReader(response)));
results.Add(result);
});
也许我正在考虑这个错误,但是如果我发送2个请求(A&amp; B)并且让B实际上先返回,我怎么能确保当我回去更新我的数据库时我正在更新正确的记录?我可以通过API调用发送ID并将其返回吗?
我的想法是创建一个请求数组,在不等待响应的情况下刻录它们,然后在另一个数组中返回这些值,然后我将在insert语句中循环。
这是一个很好的解决方法吗?我从来没有使用过Parrallel.ForEach,而且我在其上找到的所有信息对我来说都太技术化,无法用于可视化并适用于我的情况。
答案 0 :(得分:0)
也许我正在考虑这个错误,但是如果我发送2个请求(A&amp; B)并且让B实际上先返回,我怎么能确保当我回去更新我的数据库时我正在更新正确的记录?我可以通过API调用发送ID并将其返回吗?
您的所有代码都不包含任何看起来像“ID”的内容,但我认为您需要的所有内容都在URL中。如果是这种情况,一个简单的答案就是使用Dictionary而不是Bag。
List<string> urls = GetListOfUrlsFromSomewhere();
var results = new ConcurrentDictionary<string, OccupationSearch>();
Parallel.ForEach(urls.Distinct(), url =>
{
WebRequest request = WebRequest.Create(url);
string response = new StreamReader(request.GetResponse().GetResponseStream()).ReadToEnd();
var result = JsonSerializer().Deserialize<OccupationSearch>(new JsonTextReader(new StringReader(response)));
results.TryAdd(url, result);
});
完成此代码后,results
字典将包含将每个响应关联回原始网址的条目。
注意:您可能希望使用HttpClient而不是WebClient,并且应该小心处理您的一次性对象,例如: StreamReader和StringReader。