multithreading - 如何使用 AsyncCalls 调用无参数类过程?

标签 multithreading delphi delphi-7

尝试集成 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/

相关文章:

delphi - 25端口接收邮件是否可以实现SSL连接

delphi - 将 ListBox 中的字符串转换为 List<String>

delphi - 如果我只有 PID(进程 ID),则获取窗口标题

delphi - 再次使用 delphi 进行 openoffice calc

delphi - Delphi 7中如何获取当前方法的名称?

java - 如何在执行操作之前设置计时器?

java - 在 Java 的 ForkJoinTask 中,fork/join 的顺序重要吗?

Java - 切换回主线程?

C:用户(线程)不能发送消息的简单聊天程序

debugging - 防止 Lazarus 调试器分支到库单元