在CopyFileEx的回调中阻止是否安全?

dum*_*uch 7 winapi file-copying

Windows API函数CopyFileEx允许指定回调函数,然后在复制文件的一部分时调用该函数,例如向用户提供有关进度的反馈.

这在我的程序中工作正常,但我现在有一个额外的要求:我需要暂时暂停复制过程,以便将系统负载保持一段时间(可能长达几个小时),然后恢复它.这可能在任何时候发生,通常有一个大型文件(几个100千兆字节),只是部分复制,所以中止该过程并重新启动它不是一个好的选择,因为这意味着可能99%的文件,已被复制,需要再次复制.

这样做的一个选择就是在调用回调时让执行副本的线程休眠,例如

function ProgressCallback(
  _TotalFileSize, _TotalBytesTransferred, _StreamSize,
  _StreamBytesTransferred: LARGE_INTEGER;
  _StreamNumber, _CallbackReason: LongWord;
  _SourceFile, _DestinationFile: THandle; _Data: Pointer): LongWord;
  far; stdcall;
begin
  // [...]
  while gblPauseFlag do
    sleep(100);
end;
Run Code Online (Sandbox Code Playgroud)

(这当然是简化的代码.原始版本太复杂了,无法在此处发布.)gblPauseFlag将由应用程序中的另一个线程设置和重置,该线程检查要暂停的条件.

我知道有更好的方法来暂停线程(事件,关键部分或其他),但这里的问题只是:在回调函数中暂停复制线程是否安全?或者它会阻止一些Windows功能或资源?

从示例代码中可以看出,这是一个Delphi程序,但我认为这并不重要,所以我没有将问题标记为[delphi].

编辑:我可以传递标志COPY_FILE_RESTARTABLE,但是:

如果复制失败,将在目标文件中跟踪副本的进度.通过为失败的调用中使用的lpExistingFileName和lpNewFileName指定相同的值,可以在以后重新启动失败的副本.这可能会显着减慢复制操作,因为在复制操作期间可能会多次刷新新文件.

来源:CopyFileEx文档

所以我宁愿尽量避免这种情况.

小智 -1

理想情况下,当您要复制如此大的文件时,您应该使用robocopy等实用程序来复制大文件。如果您仍然喜欢编写自己的实用程序,请使其可以重新启动已中止的副本。您可以使用文件流在目标文件中存储有关副本进度的元数据。