Fill a Listbox from Thread

Hi :slight_smile:

i have an action to read some files and push their contents to a listbox, this is fine. But Xojo is a bit slow with fileoperations, so the UI is hanging, I thought i could thread this task, but how can i add things to the listbox from the thread?

You have to use a timer to actually load the ListBox. Use for instance an array string property on the window, fill it from the thread, and then use the Timer to do the actual addrow.

Oh ok wow that sounds complicated…

actual i tried this: main.Listbox1.AddRow(addon, version, “not checked…”)

how will i add this to a array (never really used them)?

What you are feeding now to addrow is an array.

  • Add the property
LoadListBox() as String

to your window or to a module. This is an Array.

  • Add a timer1 mode off, period 0 to the window

  • In your thread do

LoadListbox = Array("addon", "version", "not checked...") Timer1.Mode = Timer.ModeSingle

  • In the Timer Action event :

ListBox1.Addrow(loadlistbox) me.Mode = Timer.ModeOff

I would put the Timer as a property into the Thread. In the timer’s Action event put:

main.Listbox1.AddRow(addon, version, "not checked...")

Note: timers always execute on the main thread, even if they are a property of a thread object.

You are either running Windows OR filling tons of Rows with many ColumnsÂ…

Can we see your code to fill the Listbox?

just how many rows are you attempting to add that is so “slow”?

Yes on Windows

[quote=291930:@Michel Bujardet]What you are feeding now to addrow is an array.

  • Add the property
LoadListBox() as String

to your window or to a module. This is an Array.

  • Add a timer1 mode off, period 0 to the window

  • In your thread do

LoadListbox = Array("addon", "version", "not checked...") Timer1.Mode = Timer.ModeSingle

  • In the Timer Action event :

ListBox1.Addrow(loadlistbox) me.Mode = Timer.ModeOff[/quote]

That worked :slight_smile: Thank you for the help!

Now i only have to figure when i now the thread is over :slight_smile:

The slow thing is to search across a folder and find some files with specified extensions…

[quote=291938:@Sascha Mierke]Yes on Windows

That worked :slight_smile: Thank you for the help!

Now i only have to figure when i now the thread is over :)[/quote]

Just put an instruction at the end of the thread that sets a flag to false like ThreadIsRunning as Boolean, which you had set as True as the first instruction in the thread.

Ok this thread seems to be strange.

if my program is activated to logging things to a textfile, the thread is working. Then if i say no you dont need to log (its a option in a config file) … then the thread only get one thing in the listbox… seems to be a timing problem?

if i let sleep the thread for 1, he picksup all entries and the timer dies at end wie a outofbounds exception

Hi Sascha -

Are you using the built-in FolderItem to scan folders, or a shell using the terminal command “ls”?

If you’re using a shell with “ls”, you can pass a wildcard with the extension like this:

  theShell.Execute "cd /folder ; ls -1 *.ext"

You can also declare into FindFileFirst / FindFileNext and speed it up. I think the declares are built into the Windows Functionality Suite. Or search the forums for them.

[quote=291951:@Sascha Mierke]Ok this thread seems to be strange.

if my program is activated to logging things to a textfile, the thread is working. Then if i say no you dont need to log (its a option in a config file) … then the thread only get one thing in the listbox… seems to be a timing problem?

if i let sleep the thread for 1, he picksup all entries and the timer dies at end wie a outofbounds exception[/quote]
If you use Michel’s code, then you need to protect the array with a Semaphore or CriticalSection. I suspect that Listbox.Addrow isn’t thread-safe. It may be yielding and allowing the thread to replace the array that it is trying to load.

As an aside: when the framework was all written in C, calls like AddRow were atomic. You were pretty much guaranteed they wouldn’t yield to other threads mid-call. Now that parts of the framework are written in Xojo, that is no longer the case. Some framework calls will yield.

You may find that the thread isn’t necessary anyway, if you speed up your directory search via shell or declares.

hmm shell is a bid stupid i think cause on every OS you have to call other shell commands :frowning:

How we will get a fast directory search in xojo like in vs?

Reinventing the wheel is probably worse than using the system commands that have been optimized for best performances. Is it that difficult to have a couple conditions and commands for each system ?

Each development tool has its forte.

i tried this now

  Dim tocList() as String
  Dim tocSearch as new Shell
  Dim drive() as String = split(Preferences.addonpath, "\")
  Dim addonPath as FolderItem = GetFolderItem(Preferences.addonpath)

  'exec windows crap method
  tocSearch.Execute drive(0) +" & cd " + Preferences.addonpath + " & dir /b /s *.toc"
  
  'read lines in a array
  dim lines() as string = tocSearch.Result.Split( Chr( 10 ) )
  for l as integer = 0 to lines.Ubound -1
    if lines(l) = "" then 
    else
      tocList.Append(lines(l))
    end if 
  next l

so i read all the files in the arry tocList then i try this:

[code] 'start read process
for i As integer = 0 to tocList.Ubound

'set the file to read
Dim R as FolderItem
R= New FolderItem(tocList(i), FolderItem.PathTypeNative)

'check path depth with addonpath
Dim addondepth as integer = R.NativePath.CountFields( pathSep )
PreferencesModule.Log("TOC found", R.NativePath)

'filter path depth
if addondepth <= depth+1 then
  Dim toc as string
  Dim tocInput As TextInputStream
  Dim addon as String
  Dim version as String
  Dim Package as String
  
  'open the toc file
  Try
    tocInput = TextInputStream.Open(R)
    toc = tocInput.ReadAll
    tocInput.Close
  Catch e As IOException
    MsgBox("Error accessing file.")
  End Try
  
end if

next
[/code]

The same process runs with the xojo intern file search, but here i cant read the files…

tocInput = TextInputStream.Open® gets this error: IO exeption … that doesnt make any sense to me.

  • You should check if R is Nil.
  • I s there an error number assigned to the IOException?