Я написал код для проверки URL-адресов, однако он работает очень медленно ... Я хочу попытаться заставить его работать с несколькими URL-адресами одновременно, например с 10 URL-адресами, или, по крайней мере, сделать это как можно быстрее.
мой код:
Parallel.ForEach(urls, new ParallelOptions {
MaxDegreeOfParallelism = 10
}, s => {
try {
using(HttpRequest httpRequest = new HttpRequest()) {
httpRequest.UserAgent = "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0";
httpRequest.Cookies = new CookieDictionary(false);
httpRequest.ConnectTimeout = 10000;
httpRequest.ReadWriteTimeout = 10000;
httpRequest.KeepAlive = true;
httpRequest.IgnoreProtocolErrors = true;
string check = httpRequest.Get(s + "'", null).ToString();
if (errors.Any(new Func < string, bool > (check.Contains))) {
Valid.Add(s);
Console.WriteLine(s);
File.WriteAllLines(Environment.CurrentDirectory + "/Good.txt", Valid);
}
}
} catch {
}
});
MaxDegreeOfParallelism учитывает вычислительную мощность вашего компьютера, а не количество записей в коллекции. Если у вас двухъядерный процессор, он будет обрабатывать 2 записи параллельно. С другой стороны, браузеры могут отправлять больше запросов параллельно, но, к сожалению, не сервер.
так как я могу сделать это быстрее? как другие инструменты делают это действительно быстро? даже инструменты, которые делают то же самое, что и я
@RohitRamname Сколько вычислительной мощности будет потреблять ожидающий для 10 HTTP GET? Дай угадаю: ноль?
@SirRufo, я тоже так думаю. Я также мог бы использовать решение этой проблемы.
итак ... что я могу сделать, чтобы он работал быстрее?





Попробуйте сделать как показано ниже.
Parallel.ForEach(urls, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount - 1 }
По крайней мере, он гарантирует, что все ядра используются, оставив 1, чтобы на вашем компьютере не закончилась память.
Также обратите внимание на комментарий @KSib.
Спасибо за ответ, но с maxDegree = 10 он работал быстрее.
Маловероятно, что ваши служебные вызовы будут Привязанный к ЦП. Так что увеличение количества потоков для обработки нагрузки, возможно, не лучший подход - вы получите лучшую пропускную способность, если вместо этого будете использовать async и await, если сможете, используя более современный HttpClient вместо HttpRequest или HttpWebRequest.
Вот пример того, как это сделать:
var client = new HttpClient();
//Start with a list of URLs
var urls = new string[]
{
"http://www.google.com",
"http://www.bing.com"
};
//Start requests for all of them
var requests = urls.Select
(
url => client.GetAsync(url)
).ToList();
//Wait for all the requests to finish
await Task.WhenAll(requests);
//Get the responses
var responses = requests.Select
(
task => task.Result
);
foreach (var r in responses)
{
// Extract the message body
var s = await r.Content.ReadAsStringAsync();
Console.WriteLine(s);
}
Спасибо попробую
Будет ли это работать и с запросами POST? Если да, то дайте мне знать, как это сделать, спасибо.
По какой-то причине я продолжал сталкиваться с запросом, сообщение уже отправлено, невозможно отправить повторно. Вместо string[] я создал List<HttpRequestMessage>, а затем var requests = httpRequestMessages.Select(h => Client.SendAsync(h))
Спасибо за ответ @john, у меня есть исключение сокета при использовании этого подхода System.IO.IOException: Unable to read data from the transport connection: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. Есть идеи?
@HamzaKhanzada Похоже на проблему с сетью или, возможно, на проблему со службой; скорее всего это не связано с клиентским кодом.
да, но как я могу справиться с этим в клиентском коде? если в случае, если сеть или целевой сервер не отвечает?
@HamzaKhanzada Я не уверен, что понимаю вопрос. Как и в случае с любым исключением, вы catch и обрабатываете его любым способом, который диктуется вашими требованиями.
Будет ли этот подход работать с запросом POST? Я хочу отправить несколько файлов в API за один запрос. Я реализовал этот подход с помощью POST, но мой API не получает запрос.
@MichaelBrown Этот вопрос касается отправки нескольких запросов, а не отправки одного запроса с несколькими файлами (что значительно отличается). Предлагаю вам задать отдельный вопрос.
Кроме того, некоторые веб-серверы могут не обрабатывать ваши запросы параллельно (потому что это может выглядеть как DoS-атака или просто ограничивает количество подключений с IP-адреса). Тот факт, что вы делаете 10 параллельных запросов, не означает, что веб-сервер будет возвращать вам данные параллельно. Он по-прежнему может возвращать вам данные, как если бы вы отправили их, например, «Отправить запрос -> получить ответ -> отправить -> получить» и т. д.