AsyncCalls - 64位主线程中的Execute方法

时间:2014-02-03 11:31:36

标签: delphi asynchronous 64-bit

我现在遇到了AsyncCalls库的一些问题。我的代码片段应该在主线程中的方法中执行。

procedure MustExecInMainThread(out Result: ISuperObject); // Sorry, the parameter cannot be changed
var
  SwitchThread: Boolean;
begin   
  SwitchThread := Windows.GetCurrentThreadId <> MainThreadID;
  if SwitchThread then
    EnterMainThread;
  try
    ExecAndReturnResultsAsOutParam(Result);
  finally
    if SwitchThread then
      LeaveMainThread;
  end;
end;

完美适用于32位环境。由于EnterMainThreadLeaveMainThread与64位编译器不兼容,我尝试将代码转换为64位编译器兼容。现在代码可以编译,但会在function CheckSynchronize(Timeout: Integer = 0): Boolean;引发AV异常(System.Classes.pas)

procedure MustExecInMainThread(out Result: ISuperObject);
var
  ResultTemp: ISuperObject;
begin
  TAsyncCalls.VCLSync(procedure
  begin
    ExecAndReturnResultsAsOutParam(ResultTemp);
  end);
  Result := ResultTemp;
end;

有什么想法吗?

2 个答案:

答案 0 :(得分:2)

对于较新的Delphi版本,<{3}}不再支持EnterMainThread / LeaveMainThread。

为了在主线程中完成程序的执行,请执行以下操作:

procedure MustExecInMainThread(out Result: ISuperObject); // Sorry, the parameter cannot be changed
var
  SwitchThread: Boolean;
  ResultTemp: ISuperObject;
begin   
  SwitchThread := Windows.GetCurrentThreadId <> MainThreadID;
  if SwitchThread then begin
    TThread.Synchronize(nil,
      procedure
      begin
        ExecAndReturnResultsAsOutParam(ResultTemp);
      end
    )
    Result := ResultTemp;
  end
  else  
    ExecAndReturnResultsAsOutParam(Result);
end;

答案 1 :(得分:0)

将应用程序迁移到64位后,我仍在使用AsyncCalls。我从异步线程使用LocalVclCall来更新主窗体上的进度条,而该窗体在64位以下已不再受支持。 我很高兴发现TAsyncCalls.VCLInvoke也可以解决问题。我只是打电话

 TAsyncCalls.VCLInvoke(
    procedure
    begin
      DoVCLStuffHere
    end)

与32位相比,我没有注意到64位以下的任何(更多)问题。