@Bummi: Wie sinnfrei ist das denn? Also, gut möglich, aber wenn die einzige Referenz im Thread liegt, warum sollte ich dann noch was locken müssen? Klingt für mich nach einer ziemlichen
VCL-Nachlässigkeit bzw. Konzeptfehler. Ein Grund mehr, warum ich sowohl in Delphi als auch .NET praktisch grundsätzlich mit eignen Bitmapklassen arbeite, die ihre Daten in hübschen eindimensionalen, performaten Arrays halten. Der ganze Overhead in den diversen Grafikroutinen geht mir langsam auf die Nüsse... aber das nur so nebenbei, und ist ja nicht dein Verschulden =)
Was ich gern mache, ist einem Thread eine List<TAbzuarbeitendeObjektklasse> zu verpassen. Im Thread dann:
Delphi-Quellcode:
procedure Execute;
var
ref: TAbgearbeiteteObjektklasse;
begin
repeat
if MyTaskList.Count>0 do
begin
ref := PerformTask(MyTaskList[0]);
MyTaskList.Delete(0);
SendMessage(hwndMyMainForm, WM_MYOBJECT_READY, Integer(ref), 0); // falls nötig, dass der MainThread die Fertigstellung mitbekommen muss
// wobei ddas nicht ganz sauber ist, der MainThread muss dann gesichert "ref" verarbeitet oder kopiert haben, bevor das neue "ref" fertig ist.
// Da ggf. eine weitere Queue nehmen, oder mit Flags arbeiten.
end;
Sleep(1);
until Terminated;
end;
und im Hauptthread dann
Delphi-Quellcode:
procedure MyNewDataHandler(aObjectToHandle: TAbzuarbeitendeObjektKlasse);
begin
MyThread.MyTaskList.Add(aObjectToHandle);
end;
Und wenn die zu verarbeitenden Objekte selbst aus einem Thread stammen, bekommt der einen Callback, der o.g. Prozedur auslöst, was wahlweise auch per Windows Message hübsch sein kann. Dadurch gibts dann einen Thread, der ständig auf neue Inputs wartet, und wenn etwas kommt es fix durchrattert, so schnell wie es eben geht, und dann einfach mal fertig damit ist. Die Ergebnisse aus dem Verarbeitungsthread könnten dann ggf. in gleicher Weise an einen Speicher- oder Netzwerk-Thread übergeben werden, der dann entsprechend weiter macht. Im Grunde einfaches Queuing nach FIFO Prinzip. Macht sich für so Arbeitsthreads ganz nett.
\\Edit: Hupps, Code war LIFO, sollte FIFO sein :>
\\Edit2: Natürlich kann man PerformTask() wieder einen neuen Thread auslösen lassen, wodurch man je nach Struktur noch mehr von Multicores profitieren würde, wenn die eigentliche Abarbeitung single-threaded ist. Seit Multicores so langsam Standard sind, nutz ich solche Modelle zumindest ausschweifend =). Dann ändert sich aber natürlich die Stelle fürs Benachrichtigen des Hauptthreads.
\\Edit3: Schleife geändert... zu viel C# in letzter Zeit, ich bring alles durcheinander =)
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)