Autor |
Beitrag |
BlackMatrix
      
Beiträge: 243
Erhaltene Danke: 1
|
Verfasst: Sa 25.09.10 20:31
Hallo.
Mein Programm holt Links aus einem Quelltext, ruft diese sequentiell hintereinander auf und muss danach eine bestimmte Zeit warten, bis es erneut einen Aufruf tätigen darf. Die Zeit bis es wieder aufrufen darf, wird erst im Quelltext der Links ersichtlich.
Nun frage ich mich, wie ich das möglichst resourcenschonend hinbekomme, vielleicht sogar sequentiell, aber da fiel mir bisher keine Lösung für ein.
Jedenfalls habe ich jetzt nachdem der Quelltext der Links geladen wurde ParamterizedThreads gestartet und denen den Link,die Wartezeit und die ThreadID übergeben. Am Ende warte ich, bis alle Threads die Methode Set() aufrufen um den Mainthread wieder freizugeben:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| ManualResetEvent[] threads = new ManualResetEvent[links.Count];
for (int i = 0; i< links.Count; i++) { threads[i] = new ManualResetEvent(false);
parameter[0] = wartezeit; parameter[1] = url; parameter[2] = i;
ThreadPool.QueueUserWorkItem(Aufruf, parameter); } WaitHandle.WaitAll(threads); |
Klappt ja soweit ganz gut, aber 1. Problem, dass ist sicher nicht resourcenschonend, weil ja für jeden Link Threads gestartet werden und 2. wenn es mehr als 64 Link sind, streikt mein C# Programm und bringt eine NotSupportedException.
Jemand eine Lösung?
MfG
|
|
Kha
      
Beiträge: 3803
Erhaltene Danke: 176
Arch Linux
Python, C, C++ (vim)
|
Verfasst: Sa 25.09.10 21:12
Das hört sich aber verdächtig nach Automation einer Webseite an, erlaubt die das auch  ? Wie auch immer, was spricht gegen einen ganz normalen Timer, den du auf die kleinste Wartezeit stellst?
_________________ >λ=
|
|
BlackMatrix 
      
Beiträge: 243
Erhaltene Danke: 1
|
Verfasst: So 26.09.10 13:30
Kha hat folgendes geschrieben : | Das hört sich aber verdächtig nach Automation einer Webseite an, erlaubt die das auch ? |
Ich wüsste nicht was dagegen spricht, ich crawle nicht, mache mir nur die Bedienung durch mein Programm einfacher.
Kha hat folgendes geschrieben : | Wie auch immer, was spricht gegen einen ganz normalen Timer, den du auf die kleinste Wartezeit stellst? |
Kleinste Wartezeit? Meinst du evtl. größte Wartezeit um dann den Mainthread weiterlaufen zu lassen?
Wenn du das so meinst, müsste ich ja die Wartezeiten in eine Liste packen und dann der Methode den Parameter übergeben, dass es die größte ist, oder? Und dann könnte ich ja den Schritt weitergehen, die Wartezeiten+Links abspeichern, nach Wartezeiten ordnen (und ausrechnen) und dann sequentiell immer Warten,Webrequest,Warten,... Oder macht das Erzeugen von vielen Threads, die eh nur warten und dann einen Aufruf tätigen, resourcentechnisch nichts aus?
MfG BlackMatrix
|
|
Kha
      
Beiträge: 3803
Erhaltene Danke: 176
Arch Linux
Python, C, C++ (vim)
|
Verfasst: So 26.09.10 14:17
BlackMatrix hat folgendes geschrieben : | Ich wüsste nicht was dagegen spricht |
Entweder die AGB erlauben es oder sie tun es nicht.
BlackMatrix hat folgendes geschrieben : | Und dann könnte ich ja den Schritt weitergehen, die Wartezeiten+Links abspeichern, nach Wartezeiten ordnen (und ausrechnen) und dann sequentiell immer Warten,Webrequest,Warten,... |
Genau so meinte ich es, damit kommst allein mit dem Hauptthread aus. Aber du musst natürlich mit der kleinsten Wartezeit anfangen, nicht mit der größten.
BlackMatrix hat folgendes geschrieben : | Oder macht das Erzeugen von vielen Threads, die eh nur warten und dann einen Aufruf tätigen, resourcentechnisch nichts aus? |
Normalerweise würde ich sagen, dass sinnlos wartende Threads überhaupt kein Problem sind, solange wir nicht über einen Webserver sprechen, aber da du nicht mehr über die Exception verrätst  ...
_________________ >λ=
|
|
BlackMatrix 
      
Beiträge: 243
Erhaltene Danke: 1
|
Verfasst: So 26.09.10 16:17
Kha hat folgendes geschrieben : | Genau so meinte ich es, damit kommst allein mit dem Hauptthread aus. Aber du musst natürlich mit der kleinsten Wartezeit anfangen, nicht mit der größten. |
Da werde ich das mal so probieren. Kannst du mir noch einen Tipp geben, wie ich das realisiere? ArrayList oder ne Klasse mit Wartezeit und Link und dann irgendwie sortieren oder doch ganz anders?
|
|
Kha
      
Beiträge: 3803
Erhaltene Danke: 176
Arch Linux
Python, C, C++ (vim)
|
Verfasst: So 26.09.10 16:42
Ich würde die Wartezeiten direkt in den Zeitpunkt umrechnen und dann in einer
C#-Quelltext 1:
| SortedList<DateTime, string (* Uri *)> |
speichern. Wenn mehrere Links zur gleichen Zeit abgefragt werden müssen, müsstest du statt einer URL wohl gleich eine List<string> pro DateTime speichern.
_________________ >λ=
Für diesen Beitrag haben gedankt: BlackMatrix
|
|
BlackMatrix 
      
Beiträge: 243
Erhaltene Danke: 1
|
Verfasst: So 26.09.10 17:50
Wow ist die SortedList einfach. Da muss ja nicht mal mehr sortiert werden :]
Klappt wunderbar, hier mein Code:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| SortedList<DateTime, string> datetimeLinks = new SortedList<DateTime, string>();
foreach (string link in links) { datetimeLinks.Add(DateTime.Now.AddSeconds(wartezeit), url); }
foreach (KeyValuePair<DateTime, string> datetimeLink in datetimeLinks) { TimeSpan wartezeit = datetimeLink.Key - DateTime.Now;
if (wartezeit.TotalSeconds > 0) Thread.Sleep(wartezeit);
http.GET(datetimeLink.Value); } |
Habs noch ein klein wenig abgeändert, habe TimeSpan draus gemacht, anstatt DateTime
|
|
BlackMatrix 
      
Beiträge: 243
Erhaltene Danke: 1
|
Verfasst: Di 28.09.10 00:40
Kann ich die Keys irgendwie noch genauer definieren, denn in seltenen Fällen kommt es vor, dass 2 gleiche Timespans abgespeichert werden müssen und dann kommt eine Exception.
Ich frage mich aber, wie das sein kann, denn die TimeSpans haben Werte wie diese: 00:30:05.1875000 und sind für meine Begriffe so genau, dass ich da niemals so oft schon hätte draufstoßen können.
Oder sollte ich dann doch wieder zu DateTime und Liste greifen?
|
|
Kha
      
Beiträge: 3803
Erhaltene Danke: 176
Arch Linux
Python, C, C++ (vim)
|
Verfasst: Di 28.09.10 18:23
Für diesen Beitrag haben gedankt: BlackMatrix
|
|
BlackMatrix 
      
Beiträge: 243
Erhaltene Danke: 1
|
Verfasst: Di 28.09.10 23:17
|
|
Kha
      
Beiträge: 3803
Erhaltene Danke: 176
Arch Linux
Python, C, C++ (vim)
|
Verfasst: Mi 29.09.10 18:24
BlackMatrix hat folgendes geschrieben : | wenn ich prüfe, ob in der SortedList schon ein Eintrag ist, wenn ja den Eintrag herausholen |
Bis dahin stimmt's, aber wenn du dann die bisherige Liste in den Händen hältst, fügst du einfach den neuen Eintrag ein und bist fertig.
_________________ >λ=
Für diesen Beitrag haben gedankt: BlackMatrix
|
|
BlackMatrix 
      
Beiträge: 243
Erhaltene Danke: 1
|
Verfasst: Do 30.09.10 01:39
So ganz geheuer ist mir das nicht. Was sagst du hierzu? Stimmt das so oder ist das falsch?
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| SortedList<DateTime, List<string>> datetimeLinks = new SortedList<DateTime, List<string>>(); [...] { List<string> liste = new List<string>(); if (datetimeLinks.Keys.Contains(wann)) { datetimeLinks.Values[datetimeLinks.IndexOfKey(wann)].Add(link); } else { liste.Add(link); datetimeLinks.Add(wann, liste); } } |
|
|
Kha
      
Beiträge: 3803
Erhaltene Danke: 176
Arch Linux
Python, C, C++ (vim)
|
Verfasst: Do 30.09.10 22:38
liste würde ich erst dort erzeugen, wo sie gebraucht wird, aber ansonsten stimmt das so  .
_________________ >λ=
Für diesen Beitrag haben gedankt: BlackMatrix
|
|
|