![]() |
Probleme mit Thread in eigener Komponente
Hallo,
ich habe eine eigene Komponente entwickelt, die auch einwandfrei funktioniert. Leider darf ich den Code nicht veröffentlichen, aber das spielt auch keine Rolle, da die Komponente ja fehlerfrei funktioniert. Mithilfe eines Timers wurde jede Millisekunde eine Prozedur aufgerufen. Bei verschiedenenen Tests auf unterschiedlichen PCs viel auf, dass das ganze nicht immer performant ist, da es sein kann, dass die Prozedur länger als 1ms brauch und das hat ja zur Folge, dass alles Andere hinten dran in eine Warteschlange gesetzt wird und dann schnellt die CPU-Auslastung nach oben. Also habe ich nun alles so umgebaut, dass ich einen Thread verwende. Hier mal ein kleiner Auszug:
Delphi-Quellcode:
Nun meine zwei Probleme:
type
TDrawThread = class(TThread) private fOwner: TObject; protected procedure Execute; override; procedure Delay(msec: Longint); public constructor Create(AOwner: TObject); end; TTicker = class(TGraphicControl) private fDrawThread: TDrawThread; [...] constructor TDrawThread.Create(AOwner: TObject); begin fOwner := AOwner; inherited Create(true); end; procedure TDrawThread.Execute; begin while not Terminated do begin with (fOwner as TTicker) do begin fTick := fTick + 1; if fTick > 10000 then fTick := 0; DrawEntries; end; Delay(1); //Sleep(1); end; end; procedure TDrawThread.Delay(msec: Longint); var start, stop: Longint; begin start := GetTickCount; repeat stop := GetTickCount; until (stop - start) >= msec; end; constructor TTicker.Create(AOwner: TComponent); begin inherited Create(AOwner); fDrawThread := TDrawThread.Create(self); [...] end; 1.) Ich habe ja vorher einen Timer mit dem Intervall von einer Millisekunde verwendet. Ich habe hier nun sowohl mit Sleep(1) als auch mit Delay(1) gearbeitet, aber in beiden Fällen liegt die CPU-Auslastung bei 100% (!). Beim Timer lag sie weit unter 10%. 2.) Ich bekomme ständig vom Compiler die Fehlermeldung "Thread Error: Handle ist ungültig(6)", danach funktioniert nichts mehr. Ich kann dann gleich Delphi beenden, da nur noch AVs kommen, wenn ich irgendwas mache (Speichern, erneutes Kompilieren, etc.). Gruß Sascha |
Re: Probleme mit Thread in eigener Komponente
Zitat:
|
Re: Probleme mit Thread in eigener Komponente
DrawEntries zeichnet auf sich selber. Also auf dem Canvas vom Ticker, welcher ja von TGraphicControl kommt.
Aber auch wenn ich Synchronize verwende, bleibt der Fehler bestehen. Ich habe festgestellt, dass das Problem beim Beenden auftritt. Beim Destroy des Tickers führe ich Terminate aus und dann gebe ich das fDrawThread frei. Was merkwürdig ist: Wenn hier ein Fehler liegt und dadurch mein Programm abschmiert, ist das ja noch ok, aber selbst wenn das Programm dann beendet ist, funktioniert Delphi nicht mehr, weil überall diese Handle-Fehlermeldungen kommen und ständig AVs bzgl. der rtl10.bpl (oder so ähnlich). |
Re: Probleme mit Thread in eigener Komponente
Zitat:
Bis neulich ... |
Re: Probleme mit Thread in eigener Komponente
Wenn Du den Thread selbst freigeben möchtest, solltest Du die Eigenschaft von TThread "FreeOnTerminate" auf false setzen.
|
Re: Probleme mit Thread in eigener Komponente
Zitat:
Ein Sleep(1) = 1 Millisekunde ist wohl kaum als grosse Verzoegerung zu betrachten. Du malst also mit voller Kraft dauernd die Control neu. Delay ist noch schlimmer, da es die Zeitscheibe des Threads garnicht freigibt. |
Re: Probleme mit Thread in eigener Komponente
Das Problem ist erstmal, dass der Timer nur auf 50ms oder so genau ist, heisst selbst wenn du den Timer auf 1ms stellst und die Verarbeitung dort weniger als 1ms dauert, wird er niemals 1000mal pro Sekunde anschlagen, von daher erklärt sich auch, warum die CPU Auslastung mit dem Sleep bei 100% liegt, da er dort nun tatsächlich wesentlich öfter die Operationen ausführt. Mit dem Timer macht er es bei weitem nicht so oft.
|
Re: Probleme mit Thread in eigener Komponente
Das Problem mit den AVs habe ich gelöst. War ein ziemlich dämlicher Fehler von mir :oops:
Das hier geht ja logischerweise nicht:
Delphi-Quellcode:
@Robert: Wie mach ich das dann am besten, dass er eine Millisekunde wartet und erst dann die Schleife wieder ausführt?
Thread := Thread.Create(true);
Thread.FreeOnTerminate := true; Thread.Terminate; Thread.Free; // <--- |
Re: Probleme mit Thread in eigener Komponente
Eine Millisekunde ist viel zu kurz.
Schildere doch erst einmal was du machen willst. |
Re: Probleme mit Thread in eigener Komponente
Es wird ein Text horizontal gescrollt. Eben ein Ticker, so wie bei N24, etc. Der soll aber nun flüssig gescrollt werden, also muss die Berechnung sehr häufig aufgerufen werden.
Mit Sleep(10) sieht das ganze schon gut aus und sieht optisch genauso aus, wie beim Timer mit einem Intervall von 1. :) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:56 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