Thread & copy files

I have the bellow code and i am try to copy source to destination ,but still my app is freeze until the copy is finish…
The progress bar show the progress of copy files with no errors…
I am using a thread and timer but i think something i do wrong!!
Can someone point where i do wrong?
i have a Btn with

fSource = SelectFolder If fSource <> Nil And fsource.Exists Then fDest = SpecialFolder.Desktop.Child("test") If fDest.Exists Then CopyBar.Value = 0 Timer1.Mode = Timer.ModeMultiple // periodically check ProgressBar and update the interface Thread1.Run End If Else MsgBox "Error" End

Thread

progressValue = 0 CopyFiles (fSource,fDest) While progressValue < 100 // if not the Maximum... // recompute progressValue, a property of the Window progressValue = progressValue + 1 Dim waitUntil As Integer = Ticks + 10 While ticks < waitUntil Wend Wend

Timer

If copybar.Value >= copybar.Maximum then // tests the ProgressBar value copybar.Value = copybar.Maximum Me.Mode = Timer.ModeOff // turns off the checking/updating MsgBox "complete" Else //if not maximum // updates the interface with the current value that was updated by the thread copybar.Value = progressValue End If
Method

[code] Dim i As Integer
Dim newFolder As FolderItem
If fsource.Directory Then //it’s a folder
fMax = fsource.Count
newFolder = fDest.Child(fsource.Name)
newFolder.CreateAsFolder
For i = 1 To fsource.Count //go through each item
ProgressValue = (i)
If fsource.Item(i).Directory Then
//it’s a folder
CopyFiles(fsource.Item(i), newFolder) //recursively call this routine passing it the folder

  Else
    fsource.Item(i).CopyFileTo(newFolder) //it's a file so copy it
  End If
Next

Else //it’s not a folder
fsource.CopyFileTo(fDest)
End If[/code]
and global properties

Fdest as folderitem fsource as folderitem fMax as integer ProgressValue as integer

I dont have an answer about why this freezes the app, but I do have some notes:

Why do this at all in a thread?

Dim waitUntil As Integer = Ticks + 10 While ticks < waitUntil

You have a recursive routine.
You have no idea how many files or folders you are going to process.
So doing this:

ProgressValue = (i)

could easily set progressvalue to 2600
But your progress bar is expecting a value from 0 to 100

And the maximum number of files in a folder changes every time you recurse into a new folder.
If it was working, the progress bar would be leaping back and forth like crazy.
You dont actually set the maximum of CopyBar

you do set progressValue = progressValue + 1 in the thread, but then also
ProgressValue = (i) in the method

It has to do with how system threading works vs. how Xojo handles it’s thread system.
But in simple terms, file operations still lock up Xojo app interfaces even if threaded.

I do not know if MBS can help.

Thank you Jeff
fMax is the Global property that hold the CopyBar maximum.
But if i put copybar.maximum=fMax in the method or the thread i get >UIException
How we set the CopyBar maximum without get UIException ?

CopyFileTo doesn’t yield
Thats why this blocks - thread or no

[quote=254550:@Norman Palardy]CopyFileTo doesn’t yield
Thats why this blocks - thread or no[/quote]
Is there alternate method from CopyFileTo?

See https://forum.xojo.com/30892-progressbar-wrong-using

Yes : shell.

But you already know that and even had working code to display your progressbar in the thread you started :
https://forum.xojo.com/30848-shell-progress-bar

If you use a Shell mode 1, it is asynchronous and will release the app right away.

or write a method that uses a for or while loop and copies the file in chunks using a binary stream
that would allow yielding

We have plugin classes for file copy which also have progress and preserve extended file attributes.

Mac: http://www.monkeybreadsoftware.net/class-macfileoperationmbs.shtml
Windows: http://www.monkeybreadsoftware.net/class-windowsfilecopymbs.shtml

Greetings
Christian

[quote]Yes : shell.

But you already know that and even had working code to display your progressbar in the thread you started :
https://forum.xojo.com/30848-shell-progress-bar

If you use a Shell mode 1, it is asynchronous and will release the app right away.[/quote]
If i use the rsync command is ok for a single source to destination,but the application have multi-source to Destination,and i still trying to figure how to pass multi Source folders to rsync… for single operation…

[quote]We have plugin classes for file copy which also have progress and preserve extended file attributes.

Mac: http://www.monkeybreadsoftware.net/class-macfileoperationmbs.shtml
Windows: http://www.monkeybreadsoftware.net/class-windowsfilecopymbs.shtml

Greetings
Christian[/quote]
I will give a try to mbs.

Check https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/rsync.1.html

which gives examples about how to copy several files by a Unix pattern, or entire folders.

[quote=254583:@Michel Bujardet]Check https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/rsync.1.html

which gives examples about how to copy several files by a Unix pattern, or entire folders.[/quote]
About rsync i know how to handle it from single copy…Like i say above…
The user have 2 or 5 or 50 source paths to 1 destination folder or device.
The paths stored in listbox…
So recursive for copy the user get the paths from the listbox and proceed…
The only available shell command with progress is the rsync,and i am try to figure the MultiSource to 1 destination…
Still playing 2 days now with rsync but no success!!

Following Norman’s idea, look at https://forum.xojo.com/13247-binary-copy/0 for a method that uses BInaryStream that you can use instead of CopyFileTo in a thread.

It is easy to add a ProgressBar, with FromStream.Length and FromStream.Position. Use a timer to update the PB.

Look up “ditto” and run it in a async shell.

Thank you Sam,but ditto – copy directory hierarchies, create and extract archives, Both ditto,cp,for multi-source copy directories only with script and loops can work…
I read the Man for ditto,cp and rsync…
Thank you again.