Hallo,
ich habe ein kleines Problem mit den Methoden "TThread.Synchronize" bzw. "TThread.Queue". Ich verwende diese Methoden um Events aus meinem Audiosystem mit dem Hauptthread der
VCL zu synchronisieren. Intern fügt "Synchronize" einen Record mit den Informationen über die übergebene Funktion zu einer Liste hinzu und sendet dann via "PostMessage" die Message WM_NULL an den Hauptthread. Wird dort WM_NULL empfangen so wird die Liste der zu synchronisierenden Methoden abgearbeitet. Soweit die Theorie.
Nun ergibt sich aber folgendes Problem: Scheinbar arbeitet meine Anwendung nur dann WM_NULL ab, wenn eine andere Message eintrifft - zum Beispiel wenn die Maus bewegt wird oder ein Timer-Event ausgelöst wird. Hierdurch stauen sich in meinem eigenen Synchronisierungsthread die "Anträge". Erst wenn man die Maus eine Weile über einem Fenster der Anwendung bewegt, werden die Events nach und nach abgearbeitet.
Hier ein kurzer Codeauszug:
Delphi-Quellcode:
procedure TAuSyncMgr.Execute;
begin
try
while not Terminated do
begin
while true do
begin
FCurMem := nil;
FDeletedCurMem := false;
FCritSect.Enter;
try
if FCallList.Count > 0 then
FCurMem := PThreadMethod(FCallList[0]);
finally
FCritSect.Leave;
end;
if FCurMem = nil then
break;
try
try
{$IFNDEF DO_NOT_USE_VCL}
//Erst nach dem Abarbeiten von "FCurMem^" durch Synchronize kehrt die Funktion zurück.
//Das ist auch gut so. Jedoch wird FCurMem^ erst nach dem Eintreffen einer Windowmessage
//wie "WM_MOUSEMOVE" abgearbeitet. Das ist nicht so schön.
Synchronize(FCurMem^);
{$ELSE}
FCurMem^;
{$ENDIF}
finally
if not FDeletedCurMem then
begin
//Remove the element from the list
FCritSect.Enter;
try
FCallList.Delete(0);
//Free the memory reserved for the method pointer
FreeMem(FCurMem, SizeOf(TThreadMethod));
finally
FCritSect.Leave;
end;
end;
end;
except
//
end;
end;
Sleep(1);
end;
except
//
end;
end;
Den ganzen Code gibt es hier:
http://audorra.svn.sourceforge.net/v...21&view=markup
Hat jemand eine mögliche Lösung für das Problem? Das Ganze sollte keine Änderung am Code des Endanwenders (sprich Formulare etc.) benötigen, sondern sich auf meinen Bibliothekscode beschränken. Einen Timer zu Formular hinzuzufügen (was übrigens zu langsam ist, da ich ca. 50-100 Events pro Sekunde auf diese Weise synchronisiere), ist also keine Lösung.
Ich hoffe mir kann hier jemand helfen.
Schon einmal Danke,
Andreas