![]() |
Thread hängt wenn Listview Eintrag bekommt
Guten Abend,
ich habe ein Thread-Verständnis-Problem. Mein Programm hat in einem ListView mehrer Computer, welche alle 30 Sekunden auf Erreicgbarkeit geprüft werden. Diese erfolgt in Thread. Das Ergebnis wird an das ListView zurückgeliefert. Das funktioniert auch alles einwandfrei. Bloß wenn ich zur Laufzeit einen neuen Computer hinzufüge, kommt eine Fehlermeldung (ListIndex überschreitet das Maximum). Schließe ich das Program und starte es erneut, funktioniert es wieder. Wenn man EInträge löscht funktioniert auch alles. Was einer warum? Mein Thread
Delphi-Quellcode:
lvid ist richtig aber nach dem Hinzufügen, kommt beim ersten Benutzer der Fehler. Warum? Mit Synchronize kommt der gleiche Fehler. Was läuft da falsch? Planlos, ich hoffe auf eine Idee.
...
procedure MyThread.Execute; begin CoInitialize(nil); try if art = 'CheckServerStatus' then CheckServerStatus; if art = 'ServerStatusToXML' then //ServerStatusToXML; except on e: exception do begin // mache hier irgendetwas mit dem Fehler. end; end; CoUnInitialize(); end; ... procedure MyThread.CheckServerStatus; begin if IsHostAlive(Server) = True then begin frm_main.lv_server.Items[lvid].ImageIndex := 1; //Server Online if (status = '2') and (frm_main.FirstStart = False) then frm_main.lv_server.Items[lvid].SubItems[1] := '1' //Server Online else frm_main.lv_server.Items[lvid].SubItems[1] := ''; end else begin frm_main.lv_server.Items[lvid].ImageIndex := 2; //Server Offine if (status = '1') and (frm_main.FirstStart = False) then frm_main.lv_server.Items[lvid].SubItems[1] := '2' //Server Online else frm_main.lv_server.Items[lvid].SubItems[1] := ''; end; end; Meine Aktualisierungsroutine
Delphi-Quellcode:
procedure Tfrm_main.CheckServerStatus;
var i : Integer; Thread : MyThread; begin for i := 0 to lv_server.Items.Count - 1 do begin Thread := MyThread.Create(True); Thread.art := 'CheckServerStatus'; Thread.lvid := i; //ListView ItemIndex Thread.server := lv_server.Items[i].Caption; Thread.status := IntToStr(lv_server.Items[i].ImageIndex); Thread.FreeOnTerminate := True; Thread.Resume; end; lbl_overview_servercheck.Caption := FormatDateTime('dd. mmmm yyyy hh:nn:ss', now); end; |
Re: Thread hängt wenn Listview Eintrag bekommt
procedure Tfrm_main.CheckServerStatus;
var i : Integer; Thread : MyThread; begin for i := 0 to lv_server.Items.Count - 1 do begin Thread := MyThread.Create(True); Thread.art := 'CheckServerStatus'; Thread.excute; Thread.lvid := i; //ListView ItemIndex Thread.server := lv_server.Items[i].Caption; Thread.status := IntToStr(lv_server.Items[i].ImageIndex); Thread.FreeOnTerminate := True; Thread.Resume; end; lbl_overview_servercheck.Caption := FormatDateTime('dd. mmmm yyyy hh:nn:ss', now); end; |
Re: Thread hängt wenn Listview Eintrag bekommt
Was soll das bringen? Das kennt er so nicht und kann damit nichts anfangen.
|
Re: Thread hängt wenn Listview Eintrag bekommt
Autsch! In einen Thread auf ein Oberflächencontrol zugreifen. Das muss ja irgendwo krachen!
Wird denn ab und zu der Kommentar gelesen der in der neuen Unit mit der Thread-Klasse am Anfang steht :gruebel: |
Re: Thread hängt wenn Listview Eintrag bekommt
Hi,
also das sieht bisher ja ziemlich chaotisch aus. Und @NickelM: Execute wird vom Thread selbst aufgerufen. Sonst würde das ja auch nicht im Thread-Kontext ablaufen, sondern innerhalb des Caller-Threads, sprich hier der VCL-Mainthread. @daywalker: Wenn Du selbst schon Synchronize erwähnst, weißt Du ja auch das ein Zugriff auf VCL-Objekte immer synchronisiert erfolgen muß. Die ListView ist bestimmt nicht threadsafe... Bau entsprechende interne Variablen und Properties in den Thread ein, die Werte annehmen und entsprechende synchronisierte Callback-Methoden, um die Informationen an die Oberfläche zurückzugeben. Wenn nur am Ende zurückgegeben werden soll, kannst Du das im OnTerminate-Ereignis erledigen, da dieses im Kontext des Aufrufers, also hier des Mainthreads, erfolgt. Gruß Assertor @Bernhard: Du bist aber auch wieder schnell... ;) |
Re: Thread hängt wenn Listview Eintrag bekommt
Vielen Dank für die Hinweise. Kenne mich mit Threads noch nicht so aus. Deshalb so chaotisch. Hatte Synchronize weggelassen, da der Fehler auch kam. Ich versuch es mal mit dem OnTerminate Event.
Dank. Sven |
Re: Thread hängt wenn Listview Eintrag bekommt
Das OnTerminate Event habe ich eingebaut aber mit der Variableübergabe klappt es nicht so wirklich. Würdet ihr mir etwas mehr dazu sagen?
Delphi-Quellcode:
Wo müssen jetzt die Variablen hin damit ich sie im OnThreadTerminate verwenden kann?
procedure Tfrm_main.OnThreadTerminate(Sender: TObject);
begin ShowMessage('Am Ende'); end; procedure Tfrm_main.CheckServerStatus; var Thread : MyThread; begin for i := 0 to lv_server.Items.Count - 1 do begin Thread := MyThread.Create(True); Thread.art := 'CheckServerStatus'; Thread.server := lv_server.Items[i].Caption; Thread.FreeOnTerminate := True; Thread.OnTerminate := OnThreadTerminate; Thread.Resume; end; lbl_overview_servercheck.Caption := FormatDateTime('dd. mmmm yyyy hh:nn:ss', now); end; Vielen Dank. |
Re: Thread hängt wenn Listview Eintrag bekommt
Als Felder in deinen Thread (bzw, dann als public properties).
|
Re: Thread hängt wenn Listview Eintrag bekommt
Ich steige da immer noch nicht durch. Habe die Variabeln gesetzt aber ich kann nicht darauf zugreifen.
Thread Unit:
Delphi-Quellcode:
Meine Main Unit:
type
MyThread = class(TThread) private { Private-Deklarationen } protected procedure Execute; override; procedure CheckServerStatus; public { Public-Deklarationen } art : String; status : String; lvid : Integer; end; ... procedure MyThread.Execute; begin CoInitialize(nil); try if art = 'CheckServerStatus' then CheckServerStatus; except on e: exception do begin // mache hier irgendetwas mit dem Fehler. end; end; CoUnInitialize(); end; procedure MyThread.CheckServerStatus; begin if IsHostAlive(Server) = True then status := '1' //Server Online else status := '2'; //Server Online end;
Delphi-Quellcode:
Fehler beim Kompilieren. Siehe OnThreadTerminate Prozedure.
procedure Tfrm_main.OnThreadTerminate(Sender: TObject);
begin ShowMessage(MyThread.status); // Fehler: Methodenbezeichner erwartet. Welcher soll das sein? end; procedure Tfrm_main.CheckServerStatus; var i : Integer; Thread : MyThread; begin for i := 0 to lv_server.Items.Count - 1 do begin Thread := MyThread.Create(True); Thread.art := 'CheckServerStatus'; Thread.lvid := i; Thread.server := lv_server.Items[i].Caption; Thread.FreeOnTerminate := True; Thread.OnTerminate := OnThreadTerminate; Thread.Resume; end; lbl_overview_servercheck.Caption := FormatDateTime('dd. mmmm yyyy hh:nn:ss', now); end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:40 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz