I am writing a small app (using 2022r4.1) that will run on a Windows tablet connected to a (sometimes there) WiFi network. As such, I must have a local copy of some MSSQL data, which I have chosen to store locally using SQLite.
Normally, the data will be synchronized every minute when on WiFi and be perhaps a dozen records. Total time about 3-4 seconds. But if the device is new or has been offline for while there might be 1000 records or so, and the app hangs while bringing them in.
Enter a thread. The last time I used them it was a beautiful disaster. The threads worked beautifully, and the ODBC driver (written in the 1990s) was a disaster; it did not like multiple threads calling it. This time things are more modern.
When the updates are occurring I want to show the user a small progress bar that something is happening in the background. For this I need to use the method AddUserInterfaceUpdate and the event UserInterfaceUpdate. I prefer to do the synchronization at the App level, not specifically tied to a window, and therefore I added a Thread property a couple of handlers for the Run and UserInterfaceUpdate of this property. This is the same technique that I use to handle timers when writing services for Windows, and it works like a charm.
Thanks to both of you, but I found my problem in setting up a simple test program. I was not going deep enough into my array of dictionaries and was misreading what the debugger was telling me. Hair sufficiently pulled out, I will proceed with my original project.
However, I will show the three basic elements for anyone that might find them useful later. First the thread setup in App.Opening:
' This code appears in App.Opening
' thdTestSync is a Thread property defined in App
' Set up the thread to do something and handle updates from that something
thdTestSync = new Thread
AddHandler thdTestSync.UserInterfaceUpdate, AddressOf UpdateDisplay
AddHandler thdTestSync.Run, AddressOf TestSync
thdTestSync.Priority = 1
' Start the thread
thdTestSync.Start
Next, the updating of progress in TestSync:
' This is TestSync(t As Thread). It just updates the progress
var lngRows As Int64
for lngRows = 1 to 10
' Keep track of progress
thdTestSync.AddUserInterfaceUpdate("progress":lngRows)
Next
Return
Finally, the displaying of progress triggered by UserInterfaceUpdate:
' This is Update Display(t As Thread, dcData() As Dictionary). It shows the progress.
' dcData is an array of dictionaries. Must step through the array
for each dcEntry as Dictionary in dcData
' dcEntry is one of the dictionaries in the array. Must also step through the the dictionary, though each has only one entry
for each deList As DictionaryEntry in dcEntry
' deList is the sole Dictionary Entry in dcEntry. Show its key:value pair
wndMain.lstResults.AddRow deList.Key.StringValue + " = " + deList.Value.StringValue
next
next
Return
I think the boils the Thread handling concept down to its bare minimum.