Autor Beitrag
BlackMatrix
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 243
Erhaltene Danke: 1



BeitragVerfasst: 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:

ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Sa 25.09.10 21:12 
Das hört sich aber verdächtig nach Automation einer Webseite an, erlaubt die das auch :gruebel: ? Wie auch immer, was spricht gegen einen ganz normalen Timer, den du auf die kleinste Wartezeit stellst?

_________________
>λ=
BlackMatrix Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 243
Erhaltene Danke: 1



BeitragVerfasst: So 26.09.10 13:30 
user profile iconKha hat folgendes geschrieben Zum zitierten Posting springen:
Das hört sich aber verdächtig nach Automation einer Webseite an, erlaubt die das auch :gruebel: ?


Ich wüsste nicht was dagegen spricht, ich crawle nicht, mache mir nur die Bedienung durch mein Programm einfacher.

user profile iconKha hat folgendes geschrieben Zum zitierten Posting springen:
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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: So 26.09.10 14:17 
user profile iconBlackMatrix hat folgendes geschrieben Zum zitierten Posting springen:
Ich wüsste nicht was dagegen spricht
Entweder die AGB erlauben es oder sie tun es nicht.

user profile iconBlackMatrix hat folgendes geschrieben Zum zitierten Posting springen:
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.

user profile iconBlackMatrix hat folgendes geschrieben Zum zitierten Posting springen:
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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 243
Erhaltene Danke: 1



BeitragVerfasst: So 26.09.10 16:17 
user profile iconKha hat folgendes geschrieben Zum zitierten Posting springen:
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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: So 26.09.10 16:42 
Ich würde die Wartezeiten direkt in den Zeitpunkt umrechnen und dann in einer
ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 243
Erhaltene Danke: 1



BeitragVerfasst: So 26.09.10 17:50 
Wow ist die SortedList einfach. Da muss ja nicht mal mehr sortiert werden :]

Klappt wunderbar, hier mein Code:

ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 243
Erhaltene Danke: 1



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Di 28.09.10 18:23 
user profile iconKha hat folgendes geschrieben Zum zitierten Posting springen:
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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 243
Erhaltene Danke: 1



BeitragVerfasst: Di 28.09.10 23:17 
user profile iconKha hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconKha hat folgendes geschrieben Zum zitierten Posting springen:
Wenn mehrere Links zur gleichen Zeit abgefragt werden müssen, müsstest du statt einer URL wohl gleich eine List<string> pro DateTime speichern.
;) ?


Ich kapier das nicht, wie füge ich denn da den ValueWert der Liste hinzu, wenn da schon ein Key in der SortedList ist.

Ich mein, ich muss doch der SortedList als 2. Parameter eine Liste übergeben und das kann ich doch nur, wenn ich prüfe, ob in der SortedList schon ein Eintrag ist, wenn ja den Eintrag herausholen, ne neue Liste erstellen und beide in die Liste einfügen und am Ende wieder übergeben oder geht das auch einfacher?

MfG
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Mi 29.09.10 18:24 
user profile iconBlackMatrix hat folgendes geschrieben Zum zitierten Posting springen:
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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 243
Erhaltene Danke: 1



BeitragVerfasst: Do 30.09.10 01:39 
So ganz geheuer ist mir das nicht. Was sagst du hierzu? Stimmt das so oder ist das falsch?

ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: 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