ein schneller Weg, um mehrere Dateien herunterladen
ich brauche zum herunterladen von über 2 Millionen Dateien aus der SEC-Webseite. jede Datei hat eine einmalige url und im Durchschnitt 10kB. dies ist meine aktuelle Umsetzung:
List<string> urls = new List<string>();
//... initialize urls ...
WebBrowser browser = new WebBrowser();
foreach (string url in urls)
{
browser.Navigate(url);
while (browser.ReadyState != WebBrowserReadyState.Complete) Application.DoEvents();
StreamReader sr = new StreamReader(browser.DocumentStream);
StreamWriter sw = new StreamWriter(), url.Substring(url.LastIndexOf('/')));
sw.Write(sr.ReadToEnd());
sr.Close();
sw.Close();
}
die projizierte Uhrzeit ist 12 Tage... gibt es einen schnelleren Weg?
Edit: btw, ist der lokale Datei-handling dauert nur 7% der Zeit
Edit: dies ist meine Letzte Umsetzung:
void Main(void)
{
ServicePointManager.DefaultConnectionLimit = 10000;
List<string> urls = new List<string>();
//... initialize urls ...
int retries = urls.AsParallel().WithDegreeOfParallelism(8).Sum(arg => downloadFile(arg));
}
public int downloadFile(string url)
{
int retries = 0;
retry:
try
{
HttpWebRequest webrequest = (HttpWebRequest)WebRequest.Create(url);
webrequest.Timeout = 10000;
webrequest.ReadWriteTimeout = 10000;
webrequest.Proxy = null;
webrequest.KeepAlive = false;
webresponse = (HttpWebResponse)webrequest.GetResponse();
using (Stream sr = webrequest.GetResponse().GetResponseStream())
using (FileStream sw = File.Create(url.Substring(url.LastIndexOf('/'))))
{
sr.CopyTo(sw);
}
}
catch (Exception ee)
{
if (ee.Message != "The remote server returned an error: (404) Not Found." && ee.Message != "The remote server returned an error: (403) Forbidden.")
{
if (ee.Message.StartsWith("The operation has timed out") || ee.Message == "Unable to connect to the remote server" || ee.Message.StartsWith("The request was aborted: ") || ee.Message.StartsWith("Unable to read data from the transport connection: ") || ee.Message == "The remote server returned an error: (408) Request Timeout.") retries++;
else MessageBox.Show(ee.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
goto retry;
}
}
return retries;
}
Kann nicht diese Dateien werden in einem Archiv zusammengefasst und heruntergeladen haben, in eine Einheit?
leider Nein.
Irgendeinem Grund Sie mit einem browser-Steuerelement anstelle einer
der Grund ist, dass ich bin ratlos über die Unterschiede...
Getestet habe ich mit einem sequenziellen WebRequest, es ist sogar um 30% langsamer
leider Nein.
Irgendeinem Grund Sie mit einem browser-Steuerelement anstelle einer
WebRequest
?der Grund ist, dass ich bin ratlos über die Unterschiede...
Getestet habe ich mit einem sequenziellen WebRequest, es ist sogar um 30% langsamer
InformationsquelleAutor eyaler | 2012-01-15
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ausführen des downloads gleichzeitig, statt nacheinander, und legen Sie eine sinnvolle MaxDegreeOfParallelism sonst werden Sie versuchen, zu viele gleichzeitige Anfrage, die Aussehen wie ein DOS-Angriff:
Application.DoEvents
aus einem anderen thread wohl falsch zu sein.vereinbart, ich konzentrierte mich auf die Parallelität ohne Rücksicht auf die download-Implementierung. wird fix..
..jetzt behoben, ersetzt browser-Steuerung mit HttpWebRequest
danke, ich könnte noch ein Faktor 4 speedup mit dieser Methode (auch mit ServicePointManager.DefaultConnectionLimit = 10000;) ich denke, dies ist aufgrund von server-Beschränkungen. weitere Vorschläge?
Der Engpass ist, die ich vermute, ist die Anzahl der gleichzeitigen verbindungen pro client (IP-Adresse) an den server. Wenn du weißt, was das ist, wird der MaxDegreeOfParallelism zu passen, dieser gewann;t Erhöhung durch, aber wird verhindern, dass Anforderungen für eine Verbindung wartet. Um mehr Durchsatz, wenn Sie die Ressourcen haben, könnte man skalieren, D. H. teilen Sie die URLs zwischen n-clients, die jeweils mit einer eindeutigen IP-Adresse gleichzeitig ausgeführt werden können.
InformationsquelleAutor Myles McDonnell
Download-Dateien in mehrere threads. Anzahl der threads hängt von Ihrem Durchsatz. Betrachten Sie auch
WebClient
undHttpWebRequest
Klassen. Einfaches Beispiel:InformationsquelleAutor Kirill Polishchuk
Ich würde mehrere threads parallel, mit einem
WebClient
. Ich empfehle, die Option max degree of parallelism die Anzahl der threads, die Sie wollen, seit unbekannter Grad an Parallelität funktioniert nicht gut für lang laufende Aufgaben. Ich habe 50 parallelen downloads in einem meiner Projekte, ohne ein problem, aber abhängig von der Geschwindigkeit eines einzelnen download einen viel geringeren ausreichend sein.Wenn Sie den download mehrere Dateien parallel von einem server verwenden, sind standardmäßig begrenzt auf eine kleine Anzahl (2 oder 4) parallele downloads. Während der http-standard gibt an, wie ein low limit, dass auf vielen Servern nicht durchsetzen. Verwenden
ServicePointManager.DefaultConnectionLimit = 10000;
um den Grenzwert erhöhen.InformationsquelleAutor CodesInChaos