Ah, der Kern deiner Idee ist also folgender: Die asynchron aufzurufende Methode mit generischen Parametern wird in eine parameterlose anonyme Funktion verpackt, die nichts anderes tut, als die asynchron aufzurufende Methode mit den passenden Parametern aufzurufen. Im Kontext dieser parameterlosen anonymen Funktion sind die tatsächlichen Typen der generischen Parameter der asynchron aufzurufenden Methode bekannt und deshalb kann sie auch aufgerufen werden. Beim Empfang der Windows-Message brauche ich die Infos über die generischen Typen gar nicht, da ich nur die anonyme Funktion aufrufe (im "alten" Kontext).
Mein angepasster Quelltext:
Delphi-Quellcode:
TAsync = class
public
type
TAsyncProc = reference to procedure;
TAsyncProc1<T1> = reference to procedure(P1: T1);
class procedure Call(Proc: TAsyncProc); overload;
class procedure Call<T1>(Proc: TAsyncProc1<T1>; P1: T1); overload;
private
const
WM_ASYNCCALLINVOKE = WM_USER + $4df8;
class function AsyncCallInvoke(var m: TMessage): Boolean;
end;
...
implementation
...
class function TAsync.AsyncCallInvoke(var m: TMessage): Boolean;
var
PProc: ^TAsyncProc;
begin
case m.Msg of
WM_ASYNCCALLINVOKE:
begin
Result := True;
case m.WParam of
0:
begin
PProc := Pointer(m.LParam);
try
PProc^.Invoke;
finally
Dispose(PProc);
end;
end;
end;
end;
else
Result := False;
end;
end;
class procedure TAsync.Call(Proc: TAsyncProc);
var
PProc: ^TAsyncProc;
begin
MessageDistributor.RegisterMessageHandlerMethod(TAsync.AsyncCallInvoke);
New(PProc);
PProc^ := Proc;
PostMessage(MessageDistributor.Handle, WM_ASYNCCALLINVOKE,
0, Integer(PProc));
end;
class procedure TAsync.Call<T1>(Proc: TAsyncProc1<T1>; P1: T1);
var
PProc: ^TAsyncProc;
begin
MessageDistributor.RegisterMessageHandlerMethod(TAsync.AsyncCallInvoke);
New(PProc);
PProc^ := procedure
begin
Proc(P1);
end;
PostMessage(MessageDistributor.Handle, WM_ASYNCCALLINVOKE,
0, Integer(PProc));
end;
Vielen Dank für diese Idee!
"Seit er seinen neuen Computer hat, löst er alle seine Probleme, die er vorher nicht hatte."