AW: TThread: Synchronize() priorisieren?
Statt der Events via Methodenzeiger bevorzuge ich mittlerweile eine doppelt gepufferte Datenhaltung und Windows Messages. Beispiel:
Delphi-Quellcode:
// Threadklasse
type TMyThread = class(TThread) private FThreadBuffer: TObjectList; // Hier schreibt der Thread seine Daten rein FGUIBuffer: TObjectList; // Hier liest nachher die GUI raus FBufferCS: TCriticalSection; FForm: HWND; function GetItems: TObjectList; function GetItemCount: Integer; protected procedure Execute; override; public constructor Create(aForm: HWND); procedure LockData; procedure ReleaseData; property Items: TObjectList read GetItems; property ItemCount: Integer read GetItemCount; end; const WM_MY_DATA_UPDATE = WM_USER + 1234; implementation constructor TMyThread.Create(aForm: HWND); begin inherited(false); FForm := aForm; // Initialisierung der Buffer etc. end; procedure TMyThread.LockData; begin FBufferCS.Enter; end; procedure TMyThread.ReleaseData; begin FBufferCS.Leave; end; procedure TMyThread.GetItems: TObjectList; begin FBufferCS.Enter; try result := FGUIBuffer; finally FBufferCS.Leave; end; end; procedure TMyThread.Execute; begin repeat DoSlowStuffWith(FThreadBuffer); FBufferCS.Enter; try FGUIBuffer.Clear; // OwnsObjects! CloneAllItemsFromThreadBufferTo(FGUIBuffer); finally FBufferCS.Leave; PostMessage(FForm, WM_MY_DATA_UPDATE, 0, 0); end; until Terminated; end;
Delphi-Quellcode:
Dabei ist es dann recht egal wie lange es dauert die Daten im Thread zusammenzustellen, die GUI muss maximal auf das Kopieren der ListItems warten, was in wenigen Millisekunden erledigt ist. Dadurch wird die GUI wunderbar flott, egal wie riesig z.B. die Tabelle ist aus der die Daten erst abgerufen werden müssen im Thread. Zudem muss der Thread nicht erst warten bis die GUI all ihren Krams ins Grid gepackt hat, der kann ja ruhig schon mal den nächsten Zyklus abrufen.
// Formularklasse
type TMainForm = class(TForm) private procedure OnMyDataUpdate(var msg: TMessage); message WM_MY_DATA_UPDATE; public end; implementation procedure TMainForm.OnMyDataUpdate(var msg: TMessage); begin myThreadInstance.LockData; try WriteItemsToGrid(myThreadInstance.Items); finally myThreadInstance.ReleaseData; end; end; UND: Es ist dem Thread an sich völlig egal wer seine Daten abholt, wie der Abholer sie dann interpretiert, und ob überhaupt ein Abholer vorhanden ist. Der Code ist natürlich nur eine ganz grobe pseudocodeähnliche Skizze, und je nach Anwendungsfall kommen natürlich auch mehrere verschiedene Buffer in Frage. Auch der Typ der Buffer ist an sich egal, wichtig ist nur, dass wirklich KOPIEN existieren, nicht nur Referenzen auf dieselben Instanzen in die der Thread rein schreibt. Auch ist ein Queue-ähnlicher Aufbau denkbar, bei dem erst Items in die Thread-Liste gefüllt werden, die dann auf einen Schlag in die GUI-Liste übertragen, und dann von der GUI abgeholt und gelöscht werden. Zentral ist aber die doppelte Datenhaltung um GUI und Thread nicht zu stark aufeinander warten zu lassen, und das Signaling via Windows Message. (Gerne packe ich auch noch die self-Referenz des sendenden Threads in wParam oder lParam, damit das Formular auch gleich den richtigen Absender an der Hand hat wenn es mehrere parallele gleichtypige Threads gibt.) |
AW: TThread: Synchronize() priorisieren?
Zitat:
Generell ist Windows für Echtzeitanforderungen ungeeignet. |
AW: TThread: Synchronize() priorisieren?
Zitat:
|
AW: TThread: Synchronize() priorisieren?
Zitat:
|
AW: TThread: Synchronize() priorisieren?
Zitat:
|
AW: TThread: Synchronize() priorisieren?
Zitat:
|
AW: TThread: Synchronize() priorisieren?
Zitat:
Delphi-Quellcode:
Was ich gemeint habe, ist dass die Methode nicht als Teil des Threads deklariert werden darf:
TThread.Queue(nil, procedure()
begin MachWas; end);
Delphi-Quellcode:
type
TMeinThread = class(TThread) //... protected procedure Execute; override; procedure DoDataChanged; end; procedure TMeinThread.Execute; begin //.. TThread.Queue(nil, DoDataChanged); end; procedure TMeinThread.DoDataChanged; begin myCustomDataSource.DataChanged; end; |
AW: TThread: Synchronize() priorisieren?
Zitat:
|
AW: TThread: Synchronize() priorisieren?
Perfekt, vielen Dank!
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:09 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