Any takers?

Any takers?

The Windows API function CopyFileEx allows a callback function to be specified which is then being called when a part of the file has been copied to e.g. provide the user with feedback about the progress.

This works fine in my program, but I have now an additional requirement: I need to temporarily pause the copying process in order to keep system load low for a time (may be up to several hours) and then resume it. This may happen at any time and usually there is a large file (several 100 Gigabytes) that is only partly copied yet, so aborting the process and restarting it is not a good option, as that would mean that possibly 99% of a file that have already been copied, would need to be copied again.

One option to do that is simply let the thread that executes the copy sleep when the callback is called, e.g.

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;

(This is of course simplified code. The original is too complex to post here.) The gblPauseFlag would be set and reset by a different thread in the application that checks for the condition to pause.

I am aware that there are better ways to pause the thread (events, critical sections or whatever), but the question here is just: Is is safe to pause the copying thread in the callback function? Or would it block some Windows functionality or resources?
https://stackoverflow.com/q/49296670/49925?sgp=2

Comments

  1. IIRC, the recommended behavior would be to return PROGRESS_STOP from the callback and restart the copy process by calling CopyFileEx with the same parameters again later. I have to admit, that I never tested that by myself.

    ReplyDelete
  2. Uwe Raabe according to the documentation, making CoypFileEx restartable significantly reduces performance, that's why I would like to avoid it:
    "Progress of the copy is tracked in the target file in case the copy fails. The failed copy can be restarted at a later time by specifying the same values for lpExistingFileName and lpNewFileName as those used in the call that failed. This can significantly slow down the copy operation as the new file may be flushed multiple times during the copy operation."
    Source:
    https://msdn.microsoft.com/en-us/library/windows/desktop/aa363852(v=vs.85).aspx

    ReplyDelete
  3. Do you have any experience of the performance hit? It doesn't really sound as though performance is much of an issue for you if you want to go to sleep on the job! Anyway RbMm has given you the answer to your question.

    ReplyDelete
  4. David Heffernan Performance is actually the reason why I want to pause the copy process rather than simply aborting and restarting it.
    Background: This is on our measurement vehicles where there are large video files that must be copied between computers. If the copying takes place during measurements, it might use so many resources that the actual measurement is influenced, so it must be paused during that time but should resume immediately afterwards. The data must be in sync every evening before the computers in the vehicle can be turned off. The operator must stay with it, because the motor must be running to supply electricity. So every minute counts, because after 9 hours of driving they want to call it a day.

    ReplyDelete
  5. Why not throttle-back the data transfer instead of stopping it? Isn't there a minimal rate you can use that continues moving data but won't impact the overall timing data?

    Say, 1%, or .5% or ?

    ReplyDelete
  6. I've used low priority IO, which became available in Vista, to good effect. The system does all the heavy lifting for you.

    ReplyDelete
  7. David Heffernan so far all our attempts to update to anything later than Windows XP failed due to various reasons. But we will have to do that within the next one or two years (or move away from Windows altogether) because it gets more and more difficult to find new hardware that still supports Windows XP.

    ReplyDelete

Post a Comment