我正在编写一个应用程序,需要从不同代理向博彩公司网站执行大量并行httpwebrequests。我使用不同代理的原因是,如果有很多请求,博彩公司可以禁止ip。我的目标是尽快获得最新鲜的网站内容。 这是我的代码,包含我的所有设置:
ServicePointManager.DefaultConnectionLimit = 1000;
ServicePointManager.Expect100Continue = false;
ServicePointManager.UseNagleAlgorithm = false;
for (var i = 0; i < proxyCollection.Count; i++)
{
var proxyLocal = proxyCollection[i];
var iLocal = i;
Task.Run(async () =>
{
var httpWebRequest = (HttpWebRequest) WebRequest.Create(String.Format("https://bookmaker.com/page{0}", iLocal));
httpWebRequest.Proxy = proxyLocal;
httpWebRequest.PreAuthenticate = true;
httpWebRequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
using (var httpWebResponse = (HttpWebResponse) await httpWebRequest.GetResponseAsync())
using (var responseStream = httpWebResponse.GetResponseStream())
using (var streamReader = new StreamReader(responseStream))
{
var stringContent = await streamReader.ReadToEndAsync();
//Here i'm processing new data. It works pretty fast, so this isn't a problem
ProcessStringContent(stringContent);
}
});
}
这段代码的工作速度并不比我预期的快。
第一个问题是因为奇怪的原因所有r 请求都不会一次启动。正如我在任务管理器中看到的那样,加载有两个或更多的最大值。更多我有一个真正的快速代理,proxyCollection
包含它。但是如果我在上面的代码之后使用await Task.Delay(5000)
,在某些情况下到5000ms已经通过我的快速代理请求的那一刻甚至没有启动!
第二个问题是所有任务执行的总时间 很慢。我期望如果一个请求需要200-300ms来执行,那么并行和异步的100个请求需要更多的时间。但有时这个“更多”是10-20倍。我怀疑,有些事情是错的。
第三个问题是,当我运行此代码时,冻结了用户界面(未完全冻结,但用户界面滞后)。我读到WebRequest.Create
正在同步处理并且可以获得一些时间(dns查找,代理设置e.t.c),如果我做了很多请求,他们可以简单地填充我的所有线程(UI线程)来创建WebRequests。但我试图创建直接IP地址(WebRequest.Create(String.Format("https://10.10.10.1/page{0}", iLocal)
)的请求 - 没有改变,我正在设置代理(所以不需要自动检测代理),所以我不明白为什么创建需要这么多时间(并且创建或者可能与其他人一起出现问题?)。
请有人指出我做错了什么?我在所有ServicePointManager
设置中迷失了(我尝试过的所有设置都没有帮助)。 .Net可以处理这类任务吗?或者我可能需要使用nodejs以获得最佳性能?
P.S:代理集合不是那么大(50-100个不同的代理)。
答案 0 :(得分:0)
Back to (Parallel) Basics: Don't Block Your Threads, Make Async I/O Work For You
示例:
Parallel.For(0, 10, delegate(int i) {
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(
new Uri("http://www.mysi.com"));
string dataToSend = "Data";
byte[] buffer = System.Text.Encoding.GetEncoding(1252).
GetBytes(dataToSend);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = buffer.Length;
request.Host = "www.mysite.com";
Stream requestStream = request.GetRequestStream();
requestStream.Write(buffer, 0, buffer.Length);
requestStream.Close();
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
});