C# 如何使用WebClient和多线程获取API数据?
所以我试图查询一个可以通过HTTP(无授权)访问的API。为了加快速度,我尝试使用Parallel.ForEach循环,但似乎它运行的时间越长,出现的错误就越多 它无法检索越来越多的请求。我知道API提供商没有限制我,因为我可以在我的Internet浏览器中请求相同的阻止URL。此外,每次都有不同的失败URL,因此似乎不会出现格式错误的请求 当我使用单线程foreach循环时,似乎没有发生错误 我的故障循环如下所示:C# 如何使用WebClient和多线程获取API数据?,c#,multithreading,asynchronous,parallel-processing,webclient,C#,Multithreading,Asynchronous,Parallel Processing,Webclient,所以我试图查询一个可以通过HTTP(无授权)访问的API。为了加快速度,我尝试使用Parallel.ForEach循环,但似乎它运行的时间越长,出现的错误就越多 它无法检索越来越多的请求。我知道API提供商没有限制我,因为我可以在我的Internet浏览器中请求相同的阻止URL。此外,每次都有不同的失败URL,因此似乎不会出现格式错误的请求 当我使用单线程foreach循环时,似乎没有发生错误 我的故障循环如下所示: Parallel.ForEach(this.urlArray, singleU
Parallel.ForEach(this.urlArray, singleUrl => {
this.apiResponseBlob = new System.Net.WebClient ().DownloadString(singleUrl );
this.responsesDictionary.Add(singleUrl, apiResponseBlob);
}
正常的foreach循环工作正常,但速度非常慢:
foreach (string singleUrl in this.urlArray) {
this.apiResponseBlob = new System.Net.WebClient ().DownloadString(singleUrl);
this.responsesDictionary.Add(singleUrl, apiResponseBlob);
}
另外:我有一个PHP解决方案——我同时产生了几个“抓取器”,它从未挂断。我觉得很奇怪,PHP比C#更能处理多线程检索,所以我肯定错过了一些东西
如何以最快的方式查询API?如果没有这些奇怪的失败?您好,您是否尝试过通过同步下载来加速代码,如本问题所示(请参阅标记的答案): 您可以循环使用URI,并为每次成功下载获取回调 编辑:我已经看到你使用
this.apiResponseBlob = DL
使用多线程时,每个线程都尝试写入该变量。这可能是你的错误的一个原因。尝试使用该对象类型的实例或使用
lock{}
这样一次只有一个线程可以写入这个变量。
像
使用该调用的版本不是更容易吗?你是说与pararel.ForEach或normal ForEach循环一起使用吗?使用normal ForEach并让WbClient实例处理completion当WebClient位于其他类中时如何?我仍然可以通过只传递一个url来使用async吗?是的,您可以。但是你必须使用一个事件来响应。像这样的。e、 g.(从我的脑海中写下;)未经验证的公共类MyDownloader{public event EventHandler DlFinished;public void DLAsync(uri url){var client=new WebClient();client.DownloadStringCompleted+=(sender,e)=>{doSomeThing(e.Result);this.DlFinished(null,null);};client.DownloadStringAsync(uri)}来自其他类的用法:MyDownloader=newmydownloader;loader.DlFinished+=CallbackFunction;DlAsync(uri);希望这是可读的;)更多关于定制活动的信息:谢谢。你真的帮了大忙。
Parallel.ForEach(this.urlArray, singleUrl => {
var apiResponseBlob = new System.Net.WebClient ().DownloadString(singleUrl );
lock(singleUrl.ToString()){
this.responsesDictionary.Add(singleUrl, apiResponseBlob);
}
}