![]() |
TStringList-Zuweisung verläuft sich im Nirvana der CPU-Unit
Also als AnschlussThread zu diesem
![]()
Delphi-Quellcode:
Warum wird der Rest der GetMesswertList-Procedure nicht abgearbeitet?
procedure TForm2.Messung(iMessreihen, iMesswerte, iMessabstand: Integer);
begin // in der Messung sollen iMessreihen * iMesswerte an Messpunkten aufgenommen, um // diese später statistisch auszuwerten. // Dafür Mesthread erstellen, der in regelmäßigen Abständen die entsprechende Anzahl // an Messwerten aufnimmt. FMessThread := TMessThread.create((iMessreihen * iMesswerte), iMessabstand); try FMessThread.OnMessWertListcompleted := GetMessWertList; TempList.Messwertreihen := iMessreihen; TempList.Messwertanzahl := iMesswerte; FMessThread.WaitFor; // Auf das Ende des Threads warten. Dieser löst die GetMesswertList-Procedure aus except FMessThread.Free; end; end; procedure TForm2.GetMesswertList(Sender: TObject{; List: TStringList}); var TempStringList: TStringList; begin TempList.FsLMesswertListe := TStringList.Create; try TempList.FsLMesswertListe.Assign(FMessThread.MesswertList); // mit dem Debugger komme ich zwar irgendwo in der CPU-Unit an aber der Restliche Quellcode wird nicht mehr bearbeitet. Das Programm bleibt aber funktionstüchtig. Sämtliche Resourcen werden NICHT freigegeben, dies habe ich mit FastMM nachvollzogen. Form1.Memo1.Lines.Assign(FMessThread.MesswertList); finally FMessThread.Free; TempList.FsLMesswertListe.Free; Form1.Button1.Enabled := true; end; end; // Der TThread Type TMessThread = class(TThread) private FsLMesswertreihe: TStringList; FiMessAnzahl, FiMessabstand: integer; FCriticalSection: TCriticalSection; FOnMessWertListcompleted: TOnMessWertListcompleted; protected // Ausführung procedure Execute; override; // Setter und Getter // Eventhandling procedure DoMessWertListcompleted; public // Initialisierung und Terminierung constructor create(iMessAnzahl, iMessabstand: integer); reintroduce; destructor destroy; override; property MesswertList: TStringList read FsLMesswertreihe; // Events property OnMessWertListcompleted: TOnMessWertListcompleted read FOnMessWertListcompleted write FOnMessWertListcompleted; end; implementation uses ControlerBoardForm; constructor TMessThread.create(iMessAnzahl, iMessabstand: integer); begin inherited create(false); FsLMesswertreihe := TStringList.create; FOnMessWertListcompleted := nil; FiMessAnzahl := iMessAnzahl; FiMessabstand := iMessabstand; end; destructor TMessThread.Destroy; begin FsLMesswertreihe.Free; inherited destroy; end; procedure TMessThread.Execute; var c, i: integer; begin for i := 1 to FiMessAnzahl do begin c := GetTickcount; FsLMesswertreihe.Add(floattostr(Board.anaEingang[1])); c := {interval}FiMessabstand - (GetTickCount - c); if c > 0 then Sleep(c); end; doMessWertListcompleted; // Event wird ausgelöst, damit die MesswertListe ausgelesen werden kann. end; procedure TMessthread.DoMessWertListcompleted; begin if assigned(FOnMessWertListcompleted) then FOnMessWertListcompleted(Self{, FsLMesswertreihe}); end; end. Vielen Dank BAMatze |
Re: TStringList-Zuweisung verläuft sich im Nirvana der CPU-U
Ich habe mal an deinem Beispiel rumgebaut (mein Messwert ist natürlich nur random)
Delphi-Quellcode:
Type TMessThread = class(TThread)
private FsLMesswertreihe: TStringList; FiMessAnzahl, FiMessabstand: integer; procedure SetMessabstand(const Value: Integer); procedure SetMessanzahl(const Value: Integer); protected procedure Execute; override; public constructor create(CreateSuspended:Boolean); reintroduce; destructor destroy; override; property MesswertList: TStringList read FsLMesswertreihe; property Messanzahl:Integer read FiMessanzahl write SetMessanzahl; property Messabstand:Integer read FiMessabstand write SetMessabstand; end; type TForm1 = class(TForm) Memo1: TMemo; Button1: TButton; procedure Button1Click(Sender: TObject); private { Private-Deklarationen } FMessthread:TMessthread; procedure Messung(iMessreihen, iMesswerte, iMessabstand: Integer); procedure GetMesswertList(Sender: TObject); public { Public-Deklarationen } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Messung(iMessreihen, iMesswerte, iMessabstand: Integer); begin FMessThread:= TMessThread.create(true); FMessThread.Messanzahl:=iMessreihen * iMesswerte; FMessThread.Messabstand:=iMessabstand; FMessThread.OnTerminate := GetMessWertList; FMessthread.FreeOnTerminate:=true; FMEssthread.Resume; //TempList.Messwertreihen := iMessreihen; //TempList.Messwertanzahl := iMesswerte; { FMessThread.WaitFor; // Auf das Ende des Threads warten. Dieser löst die GetMesswertList-Procedure aus } //Wieso warten? Wozu dann der Thread, wenn du eh wartest und dein Programm lahm legst end; procedure TForm1.GetMesswertList(Sender: TObject); begin //was auch immer Memo1.lines.Assign((Sender as TMEssthread).MesswertList); {TempList.FsLMesswertListe := TStringList.Create; try TempList.FsLMesswertListe.Assign(FMessThread.MesswertList); // mit dem Debugger komme ich zwar irgendwo in der CPU-Unit an aber der Restliche Quellcode wird nicht mehr bearbeitet. Das Programm bleibt aber funktionstüchtig. Sämtliche Resourcen werden NICHT freigegeben, dies habe ich mit FastMM nachvollzogen. Form1.Memo1.Lines.Assign(FMessThread.MesswertList); finally FMessThread.Free; TempList.FsLMesswertListe.Free; Form1.Button1.Enabled := true; end;} end; constructor TMessThread.create(CreateSuspended:boolean); begin inherited create(CreateSuspended); FsLMesswertreihe := TStringList.create; end; destructor TMessThread.Destroy; begin FsLMesswertreihe.Free; inherited destroy; end; procedure TMessThread.Execute; var c, i: integer; begin for i := 1 to FiMessAnzahl do begin c := GetTickcount; //Das mit der Zeit ist noch komisch FsLMesswertreihe.Add(floattostr(random)); c := {interval}FiMessabstand - (GetTickCount - c); if c > 0 then Sleep(c); end; end; procedure TMessThread.SetMessabstand(const Value: Integer); begin FiMessabstand := Value; end; procedure TMessThread.SetMessanzahl(const Value: Integer); begin FiMessanzahl := Value; end; procedure TForm1.Button1Click(Sender: TObject); begin Messung(10,5,100); //collte ca. 5 Sekunden dauern, bis das Ergebnis da ist end; |
TStringList-Zuweisung verläuft sich im Nirvana der CPU-U
Warum löst Du das nicht, indem Du den Thread alleine entscheiden lässt, wann er fertig ist? Also einfach mit while not terminated for sich hinlaufen lassen und selbst schauen lassen, ob die Datenaufnahme gerade dran ist und wann die erforderliche Datenmenge vollständig ist.
Das hat den Vorteil, dass Du schon während der Messung Daten mit synchronize anzeigen kannst. Für das was da jetzt steht braucht man eigentlich keinen eigenen Thread. Das wäre eigentlich mit ein paar Zeilen so erledigt. Mich würde mal interessieren, ob das NotifyEvent eines Objekts, was im Hauptthread läuft, überhaupt aus einem anderen Thread ausgelöst werden kann. Grüße, Messie |
Re: TStringList-Zuweisung verläuft sich im Nirvana der CPU-U
Also erstmal Danke für deine Anregung mit dem Quellcode. Werde ich auch definitiv bei Gelegenheit testen. Habe mir gestern erstmal eine sehr schnelle Lösung erprobt, wo ich ebenfalls erstmal ohne Event mit Warten auf dem Thread meine Liste bekommen. Hier mal meine schnelle Lösung (ohne :
Delphi-Quellcode:
Funktioniert erstmal, ist sicherlich nicht sonderlich schön (Event wär mir lieber).
procedure TForm2.Messung(iMessreihen, iMesswerte, iMessabstand: Integer);
begin // in der Messung sollen iMessreihen * iMesswerte an Messpunkten aufgenommen, um // diese später statistisch auszuwerten. // Dafür Mesthread erstellen, der in regelmäßigen Abständen die entsprechende Anzahl // an Messwerten aufnimmt. FMessThread := TMessThread.create((iMessreihen * iMesswerte), iMessabstand); try FMessThread.OnMessWertListcompleted := GetMessWertList; FMessThread.WaitFor; Form1.Memo2.Lines.Assign(FMessThread.MesswertList); // vorläufige Visualisierung Templist.FsLMesswertListe := TStringList.Create; try Templist.FsLMesswertListe.Assign(FMessThread.MesswertList); // Übergabe der Messergebnisse except TempList.FsLMesswertListe.Free; end; TempList.Messwertreihen := iMessreihen; TempList.Messwertanzahl := iMesswerte; finally if assigned(TempList.FsLMesswertListe) then TempList.FsLMesswertListe.Free; FMessThread.Free; Form1.Button1.Enabled := true; end; end; MfG |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:58 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