multithreading - CopyFileEx 可以从辅助线程调用吗?

标签 multithreading delphi winapi file-copying

是否可以从线程调用 CopyFileEx 和 CopyCallback/ProgressRoutine 函数(ProgressBar.Position 将同步)?

我可以在线程中声明 CopyCallback/ProgressRoutine 函数吗?我在 @ProgressRoutine 上的 CopyFileEx 中收到错误:“需要变量”。

最佳答案

当然有可能。回调函数将在调用 CopyFileEx 的线程上下文中调用。如果您需要同步某些 UI 命令,请使用 Delphi 常用的 TThread.Synchronize,或您想要的任何其他线程间同步技术。

回调函数不能是线程类的方法。它需要与 API 指定的签名相匹配,因此它需要是一个独立的函数。正确声明后,将其传递给 CopyFileEx 时就不需要使用 @ 运算符。

function CopyProgressRoutine(TotalFileSize, TotalBytesTransferred: Int64;
  StreamSize, StreamBytesTransferred: Int64;
  dwStreamNumber, dwCallbackReason: DWord;
  hSourceFile, hDestinationFile: THandle;
  lpData: Pointer): DWord; stdcall;

您可以使用lpData参数让回调函数访问关联的线程对象。调用 CopyFileEx 时,传递对该参数的线程对象的引用:

procedure TCopyThread.Execute;
begin
  ...
  CopyResult := CopyFileEx(CurrentName, NewName, CopyProgressRoutine, Self,
    @Cancel, CopyFlags);
  ...
end;

通过访问线程对象,您可以调用该对象上的方法,包括其自己的进度例程,因此以下内容可以构成完整的独立函数。它可以将其他所有事情委托(delegate)回对象的方法。在这里,我假设该方法具有与独立函数相同的参数,但它省略了 lpData 参数,因为它将作为 Self 参数隐式传递。

function CopyProgressRoutine;
var
  CopyThread: TCopyThread;
begin
  CopyThread := lpData;
  Result := CopyThread.ProgressRoutine(TotalSize, TotalBytesTransferred,
    StreamSize, StreamBytesTransferred, dwStreamNumber,
    dwCallbackReason, hSourceFile, hDestinationFile);
end;

关于multithreading - CopyFileEx 可以从辅助线程调用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6366949/

相关文章:

c - 通知多个线程同时开始工作

ios - Delphi Datasnap 连接错误与 IPv6 (iOS)

mysql - 使用 UPDATE 的 Delphi SQL 集成

c++ - 关闭一个窗口后如何防止Win32应用程序其他窗口变为非事件状态

c++ - 如何验证运行时失败是否是由于生成的线程过多造成的?

java - LIBSVM线程安全吗

c++ - 保护多线程访问的类实例

delphi - 编译器是否优化(关闭)相同的 FieldByName 调用?

windows - 如何获取当前键盘布局的代码页?

c++ - CreateProcessAsUser 返回错误代码 2