I was waiting for a long time a FolderItem.CopyTo which does not freeze the UI (it does even if it is in a Cooperative Thread). Some weeks ago I added an option in my application to copy using a Shell command via a Shell Asynchronous and it works.
But as Xojo just added Preemptive Thread I modified my program to make the FolderItem.CopyTo in a Preemptive Thread.
It woks as expected, but if the user click a Stop button, I kill the Thread with MyPreemptiveThread.Stop . But then my application is freezed until the copy is finished! (it is as before when I copy my file in a Cooperative Thread).
Note: I synchronise 2 folders in a loop inside a Cooperative Thread called TreadSync. When I see a file to be copied, I run the Preemptive Thread called ThreadCopy which copy the file and I do ThreadSync.Pause . ThreadCopy do ThreadSync.Resume at its end (once the file is copied).
If the user click Stop, I put a Flag to true, I do ThreadCopy.Stop end ThreadSync.Resume which will exit the loop as the StopFlag is True.
I will make a sample project with a loop in a Preemptive Thread and kill it.
Download the project PremptiveThread-Kill project
and click the first button, it launch a While wend loop (which does nothing), click it again it stop the thread1. → Expected result.
Drag and drop a very big file on the left GroupBox (Source) and a folder of a slow volume (I do my test on my NAS) in the right GroupBox (Target). Click the button to copy, and click it again to stop. Nothing happens until the copy is finished.
Just change a “cancel_flag” in the “copier thread” and let it end the copy. Once it finishes, if the cancel_flag is true, delete the copy done as it was cancelled. Your app should be responsive while the background cancellation is still being completed.
If you need a faster “abort” copy, you should create your own copyto() copying blocks of data and checking for an “abort the copy” message on every block, not only at the end of the copy.
Avoid killing running threads, try finish them gracefully sending “messages” to them, like marking flags and consulting those flags in the thread and just letting the thread.run() end when the job is done properly.
No Rick, try my sample project. The app freeze when you stop the ThreadCopy. It is as if the preemptive thread become a cooperative thread, and as it is executing a single code line (FolderItem.CopyTo) the thread freeze the UI.
I don’t want to wait for the ThreadCopy to finish. If the user relaunch a synchronisation then the ThreadCopy again? And if the user stop, he expects it stop.
And the problem is that we can’t kill a thread during a single long line code (copyto or anything else), we can only kill it between 2 instructions.
Is it normal or not?
I was responding to the fact that the thread doesn’t stop immediately. If you kill a thread that is performing a long, blocking action, it’s not going to kill that action.
Effectively the CopyTo which freeze the UI is a problem we spoke about a long time ago, but I konow it would be difficult for me to write a Method as described by Rick. My Sync software offer 3 options to copy, using Xojo, Shell or AppleScript (then the Finder). On my NAS, those 3 methods don’t give the same result on certains files (modification date is the date of the copy instead of the modification date of the source file. It happens with one file I copy on my NAS, if I name it differently the problem disappear). That’s not the problem here, I just say that to explain I know that write my own method which copy file will be difficult and I will see trouble I don’t imagine right now.
Mike is right, I wanted to explain in this topic that stop a cooperative thread should not freeze the UI, and maybe we could have the option to really kill it as we do a “Force quit” to a freezed application.
Thank you Rick, I resolved my problem. I don’t kill the ThreadCopy anymore, when the user click Stop, if a long copy is in progress I show a ModalWindow explaining that the process will stop after the file being copied is finished. And the user can move the windows and he doesn’t see the multicolor ball, then he knows the application is not frozen.
The case I submit is not only for CopyTo, it is the same for every long process in a single line of code. I never use it but what if we fill a ListBox in one line with a tabulated text which contains thousand of lines? Or I don’t know if there is another instruction which can be very long.
This should not be a thread job, and there are techniques like lazy loading and paging for that at foreground, a thread job could be provisioning a data cache ahead of time for example. I guess too advanced things for the current subject, and not a “one line” thing, and we certainly can interrupt them mid flight.
No Rick, I’m glad you and other people help me. I repeat, and Mike seems to be agree, that the Thread should not lock the UI while we stop it. That’s why I filled a bug report. If Xojo close it because they assume it is normal, then it’s normal. I just wanted to point out this strange thing.
To come back to my CopyTo, I tried to lock the destination folder while the copy was in progress. I expected the copy will stop reporting an error but no, we can’t lock the destination folder while the copy is in progress, neither in the Finder. I tried to change the name of the destination folder to generate an error too, and then stop the copy. But the copy continue.
Write my own Copy Method as you describe scares me a little. I’m not a very good developper and I think there are a lot of things to think.
And last thing, when I copy a large file using the Shell Asynchronous (ditto MySourcePath MyDestPath), if the user stop the synchronisation I do MyShell.Close and it stop even if the file is not copied.
Edit: Rick, I just read your post in the XojoTracker. I didn’t post it as a feature request but because I considered it as a bug.
Xojo won’t close your request. I think I understand what probably is going on and offered a way to satisfy your need there. But it will make a one line of code in the framework become several lines of code and maybe a lot of rethinking there. Not sure when such or some other redesign may be done.