Nicht alle Threads werden bearbeitet?! ...
Huhu,
mal wieder ein Thread Problem nachdem ich den Stack Overflow wohl wegbekommen hab. Ich zeig euch erstmal ein wenig Code und erläuter dann was das Problem ist: Thread Aufruf Unit (Ausschnitt):
Code:
PROCEDURE CurrentPage(WebBrowser1:TWebBrowser; aSID:STRING; App:TApplication);
VAR temp : TStringList; ThreadArray : ARRAY of CheckThread; j : Integer; BEGIN temp := TStringList.Create; TRY GetUrls(WebBrowser1,temp); SetLength(ThreadArray,temp.Count); counter := temp.Count; // globale Variable die die Anzahl der gestarteten Threads festhält! FOR j := 0 TO temp.Count - 1 DO BEGIN ThreadArray[j] := CheckThread.Create(True); WITH ThreadArray[j] DO BEGIN SID := aSID; url := temp.Strings[j]; FIndex := j; // Indizierung der Threads FreeOnTerminate := True; Resume; END; END; WHILE ((counter <> 0) AND (uscs_form.GetGoOn)) DO // GoOn - Abbruch Variable in der Main Form App.ProcessMessages; FINALLY temp.Free; END; END; PROCEDURE ThreadReady; BEGIN dec(counter); END; Thread Unit:
Code:
Dazu schon mal die erste Frage, ist das günstig das so in einer While schleife zu
procedure CheckThread.Execute;
var IdHttp1 : TIdHTTP; Request : TStringList; MyStream : TMemoryStream; done : boolean; begin WHILE NOT(done) DO BEGIN IdHttp1 := TIdHTTP.Create(nil); Request := TStringList.Create; MyStream := TMemoryStream.Create; TRY done := False; idHttp1.RedirectMaximum := 15; idHttp1.HandleRedirects := True; TRY IdHttp1.Request.ContentType := 'application/x-www-form-urlencoded'; Request.Add('&PHPSESSID='+SID); IdHttp1.Post(url,Request,MyStream); MyStream.WriteBuffer(#0' ', 1); MyStream.Position := 0; ... done := True; EXCEPT ON Exception DO done := False; END; IF done THEN Synchronize(SendUrl); FINALLY MyStream.Free; Request.Free; IdHttp1.Free; END; END; END; gestalten? Ich werd die Exception warscheinlich dann noch spezifisch auf den Socket Error ausrichten, aber prinzipiell soll der das halt so oft probieren bis er es geschafft hat. ist das zu aufwendig weil er jedes mal die objecte neu erzeugt? Weiter Thread Unit:
Code:
PROCEDURE CheckThread.SendUrl;
BEGIN uscs_util.ThreadReady; uscs_form.UpdateFromThread(inttostr(FIndex)); // soll später eigentlich etwas anderes machen END; // übergebe zu Test Zwecken den Index Main Unit:
Code:
procedure Tuscs_form.UpdateFromThread(Furl:String);
begin IF Furl <> '' THEN uscs_result_form.LB_results.Items.Add(Furl); // Schreibt die ganzen Thread Index Nummern end; // in eine Listbox! das Problem ist jetzt wenn er z.b. 16 Threads startet, dann dauert es ein wenig aber dann sind kommen nach und nach die Index Einträge in der Listbox. natürlich nicht sortiert. das Problem ist von den 16 fehlen dann die ersten drei! Immer auch wenn es mal nur 10 threads sind oder mehr als 16. Die ersten drei fehlen irgendwie immer. und ich hab keine ahnung warum die nicht auch aufgeführt werden?! [EDIT] also sind doch nicht immer die ersten. teilweise fehlen einfach welche zwischendurch, komischerweise häufen sich aber auch der 1-3 thread die fehlen. muss ja dann irgendwie an der Execute Methode des Thread liegen. weiss aber nicht wo der fehler ist :( [/EDIT] Ist das überhaupt, günstig dass über die
Code:
Schleife darauf gewartet wird, dass alle Fertig sind?
WHILE ((counter <> 0) AND (uscs_form.GetGoOn)) DO // GoOn - Abbruch Variable in der Main Form
App.ProcessMessages; Wäre euch sehr dankbar wenn ihr mir helfen könntet! mfg emploi |
Re: Nicht alle Threads werden bearbeitet?! ...
Die VCL ist NICHT (!!!) threadsafe. Das was du machen willst, solltest du über den normalen Weg (komplette Trennung des Threads vom Hauptthread) erreichen und dann über Window Messages das Feedback an das Hauptform weitergeben. Denk dran, daß es Systeme (HT und MP) gibt, die mehrere Threads tatsächlich gleichzeitig ausführen! Da solltest du auch mit Exclusion Objects arbeiten (Mutexe, Semaphoren, Critical Sections ...). Das Problem dürfte bei dir echt daran liegen, daß die VCL eben nicht threadsafe ist.
|
Re: Nicht alle Threads werden bearbeitet?! ...
Zitat:
haste links oder sowas? danker für die antwort! mfg emploi |
Re: Nicht alle Threads werden bearbeitet?! ...
Versuche einfach die Arbeit konsequent zu trennen. Ein Arbeitsthread hat nix mit dem Form rumzufummeln. Das Form sollte entsprechend der Architektur von Windows benachrichtigt werden. Dazu gibt es zB WMs.
Ganz nebenbei macht die WHILE-Schleife eigentlich die Nutzung von Threads überflüssig, da spätestens an der WHILE-Schleife alles wieder zusammenläuft ... oder? |
Re: Nicht alle Threads werden bearbeitet?! ...
du meinst die while schleife nach dem aufruf?
ich will mit meinen threads nur erreichen das die idhttp aufrufe parallel nebeneinander ablaufen können und nicht nacheinander, weil das zu lange dauert. und damit mein programm nicht damit fortfährt die nächsten threads zu starten, damit ich nicht auf einmal 100 gestartet habe will ich halt warten das die gestarteten threads fertig sind. cool das du noch wach bist :) [EDIT] .. warst .. [/EDIT] |
Re: Nicht alle Threads werden bearbeitet?! ...
Verstehe schon, aber es gibt Funktionen die dies erledigen:
WaitForMultipleObjects() Und das parallele Ablaufen geht auch ohne, daß irgendein Zugriff auf die VCL stattfindet (unter der Annahme die Indys seien nicht teil der VCL). Die dürften doch threadsafe sein? Ich selber nutze sie nicht. |
Re: Nicht alle Threads werden bearbeitet?! ...
ok, dann werd ich es mal damit versuchen!
meinst du den zugriff auf die vcl in der Prozedur:
Code:
PROCEDURE CheckThread.SendUrl;
BEGIN uscs_util.ThreadReady; uscs_form.UpdateFromThread(inttostr(FIndex)); // soll später eigentlich etwas anderes machen END; |
Re: Nicht alle Threads werden bearbeitet?! ...
Japp.
Snychronize führt die Func im Kontext des Hauptthreads aus, das sollte also nicht zuviele Probleme geben ... müßte mir wohl mal die Indys holen um es zu testen. Wird aber vor morgen nix. |
Re: Nicht alle Threads werden bearbeitet?! ...
Hm komisch und irgendwie prägnant für das Problem ist, dass wirklich
zu 90 % die ersten 3-4 Threads bzw deren Index nicht in meiner Listbox auftreten. Synchronize wird nur aufgerufen wenn es keine Exception gegeben hat. weil nur dann ist done = true! Ich hab die Execute Procedur jetzt mal umgestellt und jetzt werden auch die threads 0-4 in meiner listbox angezeigt :) komischerweise fängt die liste damit immer an. also immer 0 - 4 in reihenfolge.die nachfolgenden Indizes die aufgelistet werden sind dann durcheinander. Kann es sein das es etwas mit den zulässigen Verbindungen des Servers zu tun hat? 0-4 werden direkt zugelassen und damit auch als erste fertig während die anderen danach in der warteschleife (also meine while schleife im thread) hängen und dann erst nach und nach abgearbeitet werden können?! irgendwie ist das alles sehr komisch.
Code:
procedure CheckThread.Execute;
var IdHttp1 : TIdHTTP; Request: TStringList; MyStream : TMemoryStream; done : boolean; begin WHILE NOT(done) DO BEGIN IdHttp1 := TIdHTTP.Create(nil); Request := TStringList.Create; MyStream := TMemoryStream.Create; TRY done := False; idHttp1.RedirectMaximum := 15; idHttp1.HandleRedirects := True; TRY IdHttp1.Request.ContentType := 'application/x-www-form-urlencoded'; Request.Add('&PHPSESSID='+SID); IdHttp1.Post(url,Request,MyStream); MyStream.WriteBuffer(#0' ', 1); MyStream.Position := 0; ... done := True; EXCEPT ON Exception DO done := False; END; FINALLY MyStream.Free; Request.Free; IdHttp1.Free; END; END; IF done THEN Synchronize(SendUrl); END; |
Re: Nicht alle Threads werden bearbeitet?! ...
Wenn der "Server" kein XP mit SP2 ist, gibt es keine Probleme.
Wenn du willst, kannst du mir mal dein Beispiel (wichtigste Stellen) als Source anhängen und per Mail an mich schicken. Kontakt: http://assarbad.net Testen wird aber vermutlich erst morgen (u.U. auch schon heute, aber unwahrscheinlich) -muß mir auch erstmal die Indys besorgen. Welches Delphi benutzt du? |
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:00 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz