Ich habe (meine URL-Liste ist etwa 1000 URLs), ich frage mich, ob es eine effektivere Aufruf mehrere URLs von der gleichen Website (bereits die Änderung der ServicePointManager.DefaultConnectionLimit
).Effektivere Methode, GetStringAsync mehrmals aufzurufen?
Auch ist es besser, die gleiche HttpClient
wieder zu verwenden oder neue bei jedem Aufruf zu erstellen, unten verwendet nur eine anstelle von mehreren.
using (var client = new HttpClient { Timeout = new TimeSpan(0, 5, 0) })
{
var tasks = urls.Select(async url =>
{
await client.GetStringAsync(url).ContinueWith(response =>
{
var resultHtml = response.Result;
//process the html
});
}).ToList();
Task.WaitAll(tasks.ToArray());
}
wie @cory
hier ist der modifizierte Code mit TPL
vorgeschlagen, aber ich die MaxDegreeOfParallelism = 100
gesetzt habe auf ca. gleiche Geschwindigkeit wie die Aufgabe zugrunde, zu erreichen, kann der folgende Code verbessert werden?
var downloader = new ActionBlock<string>(async url =>
{
var client = new WebClient();
var resultHtml = await client.DownloadStringTaskAsync(new Uri(url));
}, new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 100 });
foreach(var url in urls)
{
downloader.Post(url);
}
downloader.Complete();
downloader.Completion.Wait();
FINAL
public void DownloadUrlContents(List<string> urls)
{
var watch = Stopwatch.StartNew();
var httpClient = new HttpClient();
var downloader = new ActionBlock<string>(async url =>
{
var data = await httpClient.GetStringAsync(url);
}, new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 100 });
Parallel.ForEach(urls, (url) =>
{
downloader.SendAsync(url);
});
downloader.Complete();
downloader.Completion.Wait();
Console.WriteLine($"{MethodBase.GetCurrentMethod().Name} {watch.Elapsed}");
}
Ich würde die Anzahl der mit TPL Datenfluss empfehlen zu begrenzen Aufgaben im Flug. Eine Sache, die Sie bei Ihrer aktuellen Implementierung finden werden, ist, dass die 'HttpClient'-Anfragen tatsächlich eine Zeitüberschreitung haben können, selbst wenn sie noch nicht im Netzwerk gesendet wurden. –
So viel Parallellismus ist nutzlos, wenn Sie nicht viele Kerne auf der CPU haben, bekommen Sie nur den Thread-Hunger. Versuchen Sie '' erwarten SendAsync' anstelle von 'Post' zu verwenden, um einen Thread freizugeben, und blockieren Sie die Aufgaben nicht, verwenden Sie' warten' den ganzen Weg. HttpClient sollte von einem anderen Thread verwendet werden, also nicht jedes Mal ein neues erstellen – VMAtm
@VMAtm Ich habe 6 Kerne auf meinem Rechner, ich bin ein bisschen verwirrt, können Sie mir zeigen, wie dieser Code aussehen würde? es scheint, ich gehe zu Aufgaben als meine erste Code-Nr? – Zoinky