尝试集成 AsyncCalls在我的一个 Delphi 7 项目中,我还无法调用类的无参数过程。
我想做的事情:
TMyForm = class(TForm)
private
procedure TestCalculation;
procedure RunTest;
end;
var
TestCall: IAsyncCall;
procedure TMyForm.RunTest;
begin
TestCall := AsyncCall(TestCalculation);
end;
这是不可能的,会导致错误 E2036 Variable required(当您尝试获取表达式或常量的地址时会出现此错误消息。)。
只要我的程序具有类似于此 example 中的 WaitForIt
程序的参数,就有可能发生这种情况。 .
此外,LocalAsyncCall
是可能的,但我并不总是想声明本地过程。
如果我将其设为静态,也可以调用此过程(即 procedure TestCalculation
而不是 procedure TMyForm.TesCalculation
)。然后我可以成功调用 RunTestCall := AsyncCall(@TestCalculation, []);
但这对于属于 TMyForm
的过程不起作用。
问题
如何使用类中另一个过程中的 AsyncCalls 调用示例中的无参数类过程 (TestCalculation
)?
最佳答案
AsyncCall
希望您传递一个接收一个参数的过程。如果不想传递参数,只需添加一个并忽略即可。
procedure TestCalculation(IgnoreMe: Integer);
....
TestCall := AsyncCall(TestCalculation, 0);
您可以编写一个适配器来使调用者的代码更简洁:
type
TAsyncCallParameterlessProc = procedure of object;
function AsyncCall(Proc: TAsyncCallParameterlessProc): IAsyncCall; overload;
......
type
TAsyncCallParameterlessProcAdapter = class
private
FProc: TAsyncCallParameterlessProc;
public
constructor Create(Proc: TAsyncCallParameterlessProc);
procedure IntegerProc(IgnoreMe: Integer);
end;
{ TAsyncCallParameterlessProcAdapter }
constructor TAsyncCallParameterlessProcAdapter.Create(
Proc: TAsyncCallParameterlessProc);
begin
inherited Create;
FProc := Proc;
end;
procedure TAsyncCallParameterlessProcAdapter.IntegerProc(IgnoreMe: Integer);
begin
try
FProc;
finally
Free;
end;
end;
function AsyncCall(Proc: TAsyncCallParameterlessProc): IAsyncCall;
var
Adapter: TAsyncCallParameterlessProcAdapter;
begin
Adapter := TAsyncCallParameterlessProcAdapter.Create(Proc);
Result := AsyncCall(Adapter.IntegerProc, 0);
end;
安装该适配器后,您问题中的代码即可编译并运行。
由于 AsyncCalls 已停止使用,并且不会再次修改,因此您可以轻松地修改该代码以支持您想要的用法。
就我个人而言,我会修改 AsyncCalls
并添加 TInternalAsyncCall
的另一个子类来完成这项工作。
作为一个非常肮脏的黑客,这会起作用:
type
TAsyncCallParameterlessProc = procedure of object;
function AsyncCall(Proc: TAsyncCallParameterlessProc): IAsyncCall; overload;
.....
function AsyncCall(Proc: TAsyncCallParameterlessProc): IAsyncCall;
begin
Result := AsyncCall(TAsyncCallArgIntegerEvent(Proc), 0);
end;
这依赖于整数参数TAsyncCallArgIntegerEvent
在 volatile 寄存器中传递的事实。因此,当框架传递 0
时,您的过程不会从寄存器中读取它。
关于multithreading - 如何使用 AsyncCalls 调用无参数类过程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13861112/