Hallo zusammen,
Ich habe gerade folgendes Problem, das mich etwas stört: In einer
Unit mit einer Thread-Klasse mache ich aus dem Thread heraus einen Callback in den Main-Thread mittels TThread.Queue. Das Ganze sieht folgendermaßen aus:
Delphi-Quellcode:
procedure TMyThread.Run;
var
airplanes: IAirplanes;
begin
airplanes := ...;
...
TThread.Queue(self, procedure
begin
FCriticalSectionCallback.Enter;
try
if Assigned(FCallback) then
FCallback(airplanes);
finally
FCriticalSectionCallback.Leave;
end;
end);
end;
Die anonyme Prozedur führt dazu, die Auto-Vervollständigung von Delphi nicht mehr funktioniert. Wenn ich beispielsweise irgendwo ein "begin" schreibe und Enter drücke, wird kein "end" automatisch eingefügt, was ziemlich störend ist. Wenn ich den Inhalt der anonymen Prozedur leer mache, dann funktioniert es.
Weiß jemand, wie man das Problem vermeiden kann?
Ich habe es bereits mit der Deklaration einer Methode versucht. Problem ist hierbei allerdings, dass die Methode, die man als Parameter an TThread.Queue übergeben muss, selbst keinen Übergabeparameter haben darf (muss vom Typ "procedure of object" sein). Ich muss jedoch auf die lokale Variable "airplanes" zugreifen.
Während ich den Beitrag geschrieben habe, ist mir noch folgende Idee in den Kopf gekommen:
Delphi-Quellcode:
TMyThread = class(TThread)
strict private
procedure ExecuteCallback;
...
end;
implementation
procedure TMyThread.ExecuteCallback(const Airplanes: IAirplanes);
begin
FCriticalSectionCallback.Enter;
try
if Assigned(FCallback) then
FCallback(Airplanes);
finally
FCriticalSectionCallback.Leave;
end;
end;
procedure TMyThread.Run;
var
airplanes: IAirplanes;
begin
airplanes := ...;
...
TThread.Queue(self, procedure
begin
ExecuteCallback(airplanes);
end);
end;
Auf diese Weise funktioniert die Auto-Vervollständigung allerdings leider auch nicht. Eine weitere Idee wäre, den Parameter "airplanes" vor dem Aufruf an TThread.Queue in einem Feld zu speichern und anstatt der anonymen Prozedur eine Methode zu erstellen, die wie ExecuteCallback implementiert ist, aber keinen Übergabeparameter hat, stattdessen auf das Feld zugreift. Da bin ich mir allerdings nicht sicher, ob das threadsafe ist, weil, die Methode Run mehrmals aufgerufen wird und ich nicht weiß, ob es einen Unterschied macht, ob die an TThread.Queue übergebene Prozedur zum Zeitpunkt des zweiten Aufrufs schon ausgeführt wurde oder nicht. Ich möchte sicher sein, dass der jeweils gesetzte Wert von airplanes verwendet wird. Bei der Verwendung eines Feldes sehe ich da zumindest eine mögliche Fehlerquelle.
Hat jemand eine Lösung?