In an app created to ingest video files to a NAS using NSFileManagerMBS, I have this code in a subclass of Desktop Container in a Thread named “CopyThread”:
For i As Integer = 0 To FilesToCopy.Count - 1
Var FileName As String = FilesToCopy(i).NameWithoutExtensionMBS
Var ext As String = FilesToCopy(i).NameExtensionMBS
Var NewName As String = FileName + AddRandomToName + "." + ext
Var e As NSErrorMBS
NowCopying = NowCopying + 1
CurrentFile = FilesToCopy(i).Name
If not NSFileManagerMBS.defaultManager.copyItemMT(FilesToCopy(i), DestinationFolder.Child(NewName), e) Then
Error = e.LocalizedDescription
Else
LastFileCopied = LastFileCopied + 1
End if
Next
Finished = True
The app has four of these “Ingest Containers” and everything works perfectly and the app is responsive even while ingesting multiple files simultaneously.
The problem is that if I want to stop an ingest and send the command “CopyThread.Stop” to one of these threads, the app becomes unresponsive and I get a beach ball until the current file is copied.
Some of these video files are several GBs so it may take some time before the app becomes responsive again.
Can this be avoided?
You can’t simply stop such a thread.
You may need to add a property “cancel as boolean”, set it to true. And in the for loop check the cancel flag to exit the loop if needed quickly.
You may also want to hide the window/container if you like the user interface to update.
If you need something you can cancel, please check MacFileOperationMBS class.
I’ve tried the MacFileOperationMBS class and the files get copied, but it seems like the event StatusChanged never fires.
I wonder why?
Code in Thread:
For i As Integer = 0 To FilesToCopy.Count - 1
Var source, dest as FolderItem
Var m As new MyFileOperation
Var FileName As String = FilesToCopy(i).NameWithoutExtensionMBS
Var ext As String = FilesToCopy(i).NameExtensionMBS
Var NewName As String = FileName + AddRandomToName + "." + ext
source=FilesToCopy(i)
dest=DestinationFolder
m.CopyObject(source, dest, NewName, m.kFSFileOperationDefaultOptions,5.0)
System.DebugLog("Error: "+str(m.LastError))
Next
Finished = True
Code in the event StatusChanged in MyFileOperation:
Var path as string
if status.CurrentItem<>nil then
path=status.CurrentItem.UnixpathMBS
end if
System.DebugLog("Status Changed: "+StageString(status.Stage)+", Error: "+str(status.Error)+", Current Item: "+path)
System.DebugLog(FormatItems(status.ObjectsComplete)+" of "+FormatItems(status.TotalObjects)+", "+FormatItems(status.ObjectsRemaining)+" remaining.")
System.DebugLog("Hello from StatusChanged")
I’ve already tried the asynchron example and it works perfectly well.
But I’m not copying a directory. I’m copying an array of folderitems and I couldn’t make that work.
Does MakeFileOperationMBS work for arrays of FolderItems?
Well, it can work in your situation.
You loop over your array and start each copy process.
Then you wait for the copy to finish.
Your code makes a loop to sleep the threads for 0.1 seconds until status property reports the copy to be finished.
Unfortunately, lack of time has prevented me from experimenting further with MacFileOperationMBS.
I have chosen your idea with a “Cancel as Boolean” and it works fine. However, you have to wait for the current transfer to finish - but the app is responsive and you can continue working in the other “Ingest Containers”.
Thanks for your help