I’m using Task class to perform some processes with pictures (conversion, database saving, etc) and at same time updating a progress bar.
I have noticed that in Mac it works “almost” fine and the progress bar updates from the very first moment but steps are not regular, in Windows it waits a few seconds until it starts and then steps are regular.
This are the times in miliseconds:
First column in each type of computer is for the time spend in the process (7 pictures in total) and the second column shows the time until UpdateUI works (counter in the UpdateUI event of Task).
As you may see there is a delay of almost 5 seconds (5091 - 703) for the first UI update in Windows, then it updates regularly; total time spend for updating the UI is longer than the process.
In Mac ther is not so much delay (1823 - 1299) at first but later it becomes a bit erratic showing progress for 2 steps almost together.
Please notice that my Windows computer is faster than the iMac (even being a new one )
I need to minimize the delay on the start but haven’t found any solution: using DelayMBS, Timers, app.yieldtonextthread, app.doevents ( I know, I know ).
Any help for getting a smooth progress bar is appreciated.
Windows:
Each file processing takes 700ms, first UI update happens only after 4300ms (after the end of first file); then it updates UI very fast (each 200ms) until processing and UI updates are more similar.
Mac:
Each file processing takes 1200ms (slower computer), first UI happens after 600ms, then it updates a bit erratically (2 steps each time) until the end.
Thread si processing files at a continuos rate of 700ms for Windows and 1200ms for Mac but UpdateUI is working at a very different rhythm.
Basically I’m using the Task class from the examples, just a lot more code in the Run event and at end of each file a call to UpdateUI with args to update a progress bar.
Ok, I have been able to reproduce the problem with the original UIThreadingWithTask example. Please open this project from the examples and replace the Run event code with following:
Dim progressValue As Integer
While progressValue < 100
progressValue = progressValue + 1
Dim fi as FolderItem = SpecialFolder.Documents.Child("IMG_0183.JPG")
if fi <> nil and fi.exists then
Dim Spic as Picture = Picture.Open(fi)
if sPic <> nil then
Dim ThisPic as Picture = new Picture(sPic.Width/2,sPic.Height/2,32)
if ThisPic <> nil then
ThisPic.Graphics.DrawPicture(sPic,0,0,ThisPic.Width,ThisPic.Height,0,0,sPic.Width,sPic.Height)
end if
end if
end if
Me.UpdateUI("UIProgress":progressValue)
Wend
Being IMG_0183.JPG a 4MB picture (3600x2700pixels). Loop opens the picture and resizes it, only for testing purposes.
In Windows the progress bar starts to update at the middle of the bar, after 15 seconds without any update, then it stops again until almost the end.
Throw in an app.YieldToNextThread or me.Sleep command after UpdateUI. You’re monopolizing the cpu in your thread. Threads have the opportunity to yield at loop boundaries, but they aren’t guaranteed to. Each OS (and version of Xojo) acts differently in this regard. It’s up to you as the programmer to smooth it out by yielding/sleeping periodically.