Having an issue with threads and files

I’ve spent the last couple of days trying to come up with a solution for this, and I can’t seem to find one. I’m trying to do something very simple.

I need to convert my app’s data structure from the previous version’s format to the new one. I want to present the user with a window that shows this upgrade process.

Behind the scenes, I need to loop through every file inside the data folder and re-write the text and modify the folder structure of the files. I can do all of that just fine. But I want to present the user with a simple progress bar. These databases can be quite large, and while the conversion only takes about 10-15 seconds, having the program lockup and beachball is not a good user experience, especially when dealing with their data.

I’ve tried running the code in a thread and using the UpdateUI method inside the thread, but this ends up completely crashing the thread, and the program freezes.

I’ve tried doing the initial folder loop outside of a thread, and only running the thread on each folder. This way I can set the progress bar from outside the thread. But then I get a ThreadAccessingUI exception, even though I never do any UI work inside the thread and I wait until the thread is completed before calling it again with the next folderitem.

How can I get this to work? It seems like such an unbelievably simple concept, but I’ve been coming up empty and feel like I must be missing something.

Thanks for any advice you guys can provide!

Thread doesn’t have an UpdateUI method, so are you using the deprecated Task class?

If so, try a straight Thread embedded in your window, call AddUserInterfaceUpdate and implement the UserInterfaceUpdate event.

If that still doesn’t work, please give us more detail about what “crashing the thread” means, and maybe post your Thread code?

You can also consider my Looper class. It lets you process a large job but uses a Timer to break it up so the UI remains responsive.

Thanks Kem. I am using the new Thread with the AddUserInterfaceUpdate method. Here is some sample code, that simply adds the file name being processed to a debug textfield. When I run this, the application immediately hangs (no text is ever added to the debug field), and I must force-quit the compiled application.

This code crashes before I even do anything with the data, I’m simply trying to loop through it and update a progressbar. Before I updated the debug textfield, the program didn’t crash, but the progressbar never moved at all. It just stayed frozen with a beachball anyway, and then went to the “finished” view. So I added the debug to update the textfield, and that’s when it crashes.

I already set the progressbar’s maximum value when loading the myDataFolders folderitem array.

for i as integer=1 to uBound(myDataFolders)
  Me.AddUserInterfaceUpdate("pBarValue":i) // update the progressbar
    dim f as folderItem=myDataFolders(i)
    if f<>nil and f.exists then // the data folder exists, let's proceed
    dim fc as integer=f.count-1
    
    for x as integer=1 to fc // loop through every file and convert it
      Me.AddUserInterfaceUpdate("doDebug":f.item(x).name)
      end if
    next
  end if
next

I just restarted my computer to see what would happen, and now it no longer crashes. That’s good. But it still locks up with the beachball, remains frozen for about 25 seconds, and then the textfield refreshes with all of the lines at once. And the progressbar still never moves. I’ll take a look at your Looper class.

Thanks Kem.

Make sure you call

Self.Sleep

Inside that for loop to yield time to the app.

What code have you in the UserInterfaceUpdate event to change the progress bar?

Possibly put a:

me.sleep (10)

at the end of each loop so that other threads (including the main thread) can get a look in.

Low tech solution:
Create a text file in the folder that holds a value about which files have been done.

Do your updates in a thread
have a Timer fire every so often, read the file, and update the screen

Holy cow. I knew I was missing something super simple. THANK YOU Greg and Tim. Adding the sleep line fixed it. I never knew about that little tidbit. Been using threads for years. I feel silly. Learn something new every day! +1 to Jeff as well, that is a clever idea.

Forum for Xojo Programming Language and IDE. Copyright © 2021 Xojo, Inc.