Ich habe diese "threadsafe" generische Eigenschaft erstellt, die ich zwischen dem Hauptthread und einem Hintergrundthread verwenden kann. Ich habe es geschafft, weil ich es leid war, Lock-Objekte für all meine Eigenschaften und Variablen zu erstellen.Generic ThreadSafe Eigenschaft
TLockedProp<MyType> = class
private
FMyProp:MyType;
PropLock:TObject;
procedure SetMyProp(const Value: MyType);
function GetMyProp: MyType;
published
property Value:MyType read GetMyProp write SetMyProp;
public
Constructor Create;
Destructor Destroy;override;
end;
{ TLockedProp<MyType> }
constructor TLockedProp<MyType>.Create;
begin
inherited;
PropLock:=TObject.create
end;
destructor TLockedProp<MyType>.Destroy;
begin
PropLock.Free;
inherited;
end;
function TLockedProp<MyType>.GetMyProp: MyType;
begin
TMonitor.Enter(PropLock);
result := FMyProp;
TMonitor.Exit(PropLock);
end;
procedure TLockedProp<MyType>.SetMyProp(const Value: MyType);
begin
TMonitor.Enter(PropLock);
FMyProp := Value;
TMonitor.Exit(PropLock);
end;
Gibt es irgendwelche Probleme, die ich übersehe? Dies ist ein Code, der diese Eigenschaftenklasse verwendet. Sag mir was du denkst.
TBgThread=class(TThread)
private
FPaused: TLockedProp<boolean>;
FCount:TLockedProp<integer>;
procedure ChangeCount(pPlusMin:integer);
function GetPaused:boolean;
function GetCount:integer;
public
constructor Create;
destructor Destroy;override;
{Toggle Pause}
procedure PausePlay;
protected
procedure Execute;override;
published
Property Paused:boolean read GetPaused;
Property Count:integer read GetCount;
end;
constructor TBgThread.Create();
begin
inherited Create(true);;
FPaused:=TLockedProp<boolean>.create;
FPaused.Value:=false;
FCount:=TLockedProp<integer>.create;
FCount.Value:=0;
end;
destructor TBgThread.Destroy;
begin
FPaused.Free;
FCount.free;
inherited;
end;
procedure TBgThread.Execute;
begin
inherited;
Repeat
if not Paused then begin
Try
//do something
finally
ChangeCount(+1);
end;
end else
Sleep(90);
Until Terminated;
end;
function TBgThread.GetCount: integer;
begin
Result:=FCount.Value;
end;
procedure TBgThread.ChangeCount(pPlusMin: integer);
begin
FCount.Value:=FCount.Value+pPlusMin;
end;
function TBgThread.GetPaused: boolean;
begin
result := FPaused.Value;
end;
procedure TBgThread.PausePlay;
begin
FPaused.Value:=not FPaused.Value;
end;
Thnx für Ihre Antwort, und ich schätze die Tatsache, dass Sie Ihre Version der Klasse freigegeben haben. Dadurch fühle ich mich als Programmierer sicherer, dass ich diese Lösung selbst entwickeln konnte. nur 1 Jahr Delphi unter meinem Gürtel;). –
Beachten Sie, dass ein kritischer Abschnitt Leistungsprobleme haben kann, wenn die Klasse, die seinen Puffer enthält, kleiner als die CPU-Cache-Zeile ist. Siehe https://www.delphitools.info/2011/11/30/fixing-tcriticalsection/ Es kann besser/sicherer sein, einen kleinen Ausrichtungspuffer zur Klassendefinition hinzuzufügen und sich auf den kritischen Abschnitt des Betriebssystems anstelle der TCriticalSection-Klasse zu verlassen . –