![]() |
Problem mit Thread und ProgressBar
Hallo,
ich habe ein Programm mit einem Thread. In diesem Thread werden im Execute 5 Proceduren aufgerufen, abhängig ob jeweils eine Variable aktiv ist oder nicht. Nach jeder Procedure wird eine Procedure mit Synchronize aufgerufen, die dann im Hauptthread eine ProgressBar-Position ändert. Beim Debuggen fällt mir auf, dass nach jeder Procedure der Code für die ProgressBar-Positions-Änderung aufgerufen wird. Die ProgressBar ändert aber erst die Position wenn der Thread nicht mehr läuft. Hätte jemand eine Idee, was das Problem sein könnte? |
Re: Problem mit Thread und ProgressBar
Zitat:
|
Re: Problem mit Thread und ProgressBar
Liste der Anhänge anzeigen (Anzahl: 1)
hier mal das projekt
|
Re: Problem mit Thread und ProgressBar
Windows Vista/Seven?
Da ändert sich die ProgressBar nicht sofort, sondern paßt sich stetig an (liegt an Windows) |
Re: Problem mit Thread und ProgressBar
Zitat:
|
Re: Problem mit Thread und ProgressBar
Zitat:
|
Re: Problem mit Thread und ProgressBar
Zitat:
Interessanterweise hab ich auch andere Projekte mit ner Progressbar die sich ständig ändert, aber in diesen Projekte funktionierts problemlos. Ich seh nur keinen Unterschied wieso es bei dem einem funktioniert, beim Anderen aber nicht |
Re: Problem mit Thread und ProgressBar
zurücksetzen passiert quasi sofort
Lösung:
Delphi-Quellcode:
bzw.
PB.Position := i + 1;
PB.Position := i;
Delphi-Quellcode:
PB.Position := Max(i + 1, PB.Max - 1);
PB.Position := i; |
Re: Problem mit Thread und ProgressBar
Zitat:
Hab deine Codes mal getestet, leider ändert sich nichts am Verhalten |
Re: Problem mit Thread und ProgressBar
Da ich nichts von {APPTYPE CONSOLE} und WriteLn - Ausgaben sehe: Hast Du den abwechselnden Aufruf beim Debuggen vielleicht mit Haltepunkten hervorgerufen? Vielleicht kommt das Formular dank zahlreicher Sync-Anfragen garnicht zum neuzeichnen. Ob die Position sich überhaupt ändert könnte vermutlich ein nachgeschaltetes ProcessMessages zeigen.
Grüsse, Dirk |
Re: Problem mit Thread und ProgressBar
Zitat:
aber es nützt nichts. Ich sehe aber, dass diese Procedur angesprungen wird, bzw. durchlaufen wird aber die Progressbar geht nicht. Ich hab auch mal versucht, ein Label beschreiben zu lassen, aber auch das passiert erst, wenn der Thread zu ende ist [Edit] Ich hab jetzt mal einen Test gemacht und hab festgestellt, dass sich da irgendwas "ansammelt". Denn, wenn ich im Thread nach der try/finally-Block ein Sleep(10000) einsetzt, dann seh ich dass die Progressbar auf einmal aufgebaut wird und danach erst beendet sich der Thread (nach Ablauf der Sleep-Zeit).
Delphi-Quellcode:
procedure TThreadUnit.Execute;
var b_Allgemein: Boolean; b_Kanal : Boolean; b_Achse : Boolean; b_Antrieb : Boolean; b_Anzeige : Boolean; StringList_NCUpgrade: TStringList; begin inherited; //Variablen leeren i_Anzahl_Allgemein := 0; i_Anzahl_Kanal := 0; i_Anzahl_Achse := 0; i_Anzahl_Antrieb := 0; i_Anzahl_Anzeige := 0; //NC-Upgradefile als String holen Synchronize(NCUpgrade_holen); //Maschinendaten-Auswahl holen Synchronize(MDAuswahl_holen); //Variablen beschreiben b_Allgemein := (i_MDAuswahl and 1) = 1; b_Kanal := (i_MDAuswahl and 2) = 2; b_Achse := (i_MDAuswahl and 4) = 4; b_Antrieb := (i_MDAuswahl and 8) = 8; b_Anzeige := (i_MDAuswahl and 16) = 16; //StringList erzeugen StringList_NCUpgrade := TStringList.Create; try StringList_NCUpgrade.Text := S_NCUpgrade; //wenn die CheckBox "Allgemein" aktiv ist, dann die MD´s "Allgemein" auslesen If b_Allgemein then begin i_Anzahl_Allgemein := Allgemein_Maschinendaten_auslesen(StringList_NCUpgrade); Synchronize(MDAuslesen_fertig); end; //wenn die CheckBox "Kanal" aktiv ist, dann die MD´s "Kanal" auslesen If b_Kanal then begin i_Anzahl_Kanal := Kanal_Maschinendaten_auslesen(StringList_NCUpgrade); Synchronize(MDAuslesen_fertig); end; //wenn die CheckBox "Achs" aktiv ist, dann die MD´s "Achs" auslesen If b_Achse then begin i_Anzahl_Achse := Achs_Maschinendaten_auslesen(StringList_NCUpgrade); Synchronize(MDAuslesen_fertig); end; //wenn die CheckBox "Antrieb" aktiv ist, dann die MD´s "Antrieb" auslesen If b_Antrieb then begin i_Anzahl_Antrieb := Antrieb_Maschinendaten_auslesen(S_NCUpgrade); Synchronize(MDAuslesen_fertig); end; //wenn die CheckBox "Anzeige" aktiv ist, dann die MD´s "Anzeige" auslesen If b_Anzeige then begin i_Anzahl_Anzeige := Anzeige_Maschinendaten_auslesen(StringList_NCUpgrade); Synchronize(MDAuslesen_fertig); end; finally //StringList löschen und freigeben FreeAndNil(StringList_NCUpgrade); end; sleep(10000); //mit MainForm-Procedure synchronisieren Synchronize(fertig); end; |
Re: Problem mit Thread und ProgressBar
Hallo Helmi,
ich habe heute schon zu lange vor dem Rechner gesessen, um noch alles durchzulesen. Mir fällt aber inherited auf. Ich weiß nicht, was der Thread dann alles Ererbtes macht. Das habe ich so noch nie benutzt und auch noch nie davon gehört. Vielleicht lässt Du das mal weg. Abgesehen davon musst Du natürlich immer darauf achten, dass niemand Anderes auf denselben Speicher zugreift (es ist keine Synchronisation mit anderen Threads sichtbar) Grüße, Messie |
Re: Problem mit Thread und ProgressBar
Zitat:
|
Re: Problem mit Thread und ProgressBar
Zitat:
Es gibt nur einen Thread (jedenfalls von mir erzeugtem Thread) und da ist meines Wissens nach keine Synchronisation mit einem anderen Thread vorhanden |
Re: Problem mit Thread und ProgressBar
Versuch mal
Delphi-Quellcode:
an Stelle des Synchronize - Aufrufs (event. auch noch mit zusätzlichem Sleep(0);). Vielleicht wacht der MainThread darüber aus dem Idle / CheckSynchronize auf. Unter D7 / XP kann ich das Problem leider nicht nachvollziehen.
PostMessage(MainForm.Progressbar.Handle, PBM_SETPOS,
MainForm.Progressbar.Position + 1, 0); |
Re: Problem mit Thread und ProgressBar
Konsequenter wäre es, wenn die mit Synchronize aufgerufenen Routinen Teil des Threads wären. Bei Dir sind sie global deklariert und gehören damit eigentlich dem MainThread. Wenn Du dort das Anpassen des Progressbar aufrufst, würde ich ein Application.ProcessMessages nach Aufruf der Routine des MainForm platzieren.
Grüße, Messie |
Re: Problem mit Thread und ProgressBar
Zitat:
Das ProcessMessages nix bringt hat er doch schon erwähnt. |
Re: Problem mit Thread und ProgressBar
Die Progressbar läuft jetzt nur einmal durch, bzw. die soll?
Und die PB mal rückwärts laufen zu lassen ändert auch nix an der Darstelung?
Delphi-Quellcode:
Wie gesagt, seit Vista hat MS die Darstellung geändert und jetzt läuft sie halt nicht mehr ruckartig
PB.Position := PB.Max - i - 1;
z.B. vom Pos=10 gleich auf Pos=30, sondern sie bewegt sich "langsam" (Pixelweise) auf den neuen/aktuellen Wert zu. Aber beim einem Rückschritt (Pos wurde kleiner) soll sie sich angeblich sofort/sprungartig auf den neuen Wert bewegen. |
Re: Problem mit Thread und ProgressBar
Zitat:
Die mit Synchronize aufgerufenen Routinen sind im private-Bereich des Threads deklariert - und so Teil des Threads. Nur darin werden dann Proceduren der MainForm aufgerufen |
Re: Problem mit Thread und ProgressBar
Hallo,
ich hatte auch ein ähnliches Problem vor kurzem, da hat der Thread erst deutlich nach einer Aktion die Anzeige der geänderten Form aktualisiert. ![]() Hoffe das hilft dir vieleicht etwas BAMatze |
Re: Problem mit Thread und ProgressBar
Zitat:
Das Verhalten ist noch immer das gleiche. Wenn du die Komponenten: VistaMan: TVistaMan; VistaAltFix: TVistaAltFix; OneInstance: TOneInstance; und die Uses-Klauseln: VistaMan, VistaAltFix, OneInstance rauslöscht, dann müsste es gehen zu kompilieren. |
Re: Problem mit Thread und ProgressBar
Liste der Anhänge anzeigen (Anzahl: 2)
Ich habe im Anhang mal ein Beispül-Projekt angehängt (Source und Exe).
Der Thread tut watt und die ProgressBar auf dem Form wird brav aktualisiert. Die Programm-Teile sind getrennt in Arbeitsteil (Thread) und Anzeigeteil (Form). Dieses funktioniert so unter Vista x32 und Windows 7 x64. cu Oliver axo: Thread starten mit Klick auf den Button (wer hätte das vermutet) :mrgreen: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:45 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