HI Guys,
I have an app which uses threads AND TCPsockets and methods.
All of these can read and write to a listbox
I have tried several ways to lock the listbox while it is being updated by a EasyTCPsocket so the methods and Threads cant use it.
Does anyone have a absolute bullet proof- no getting around it- written in stone - solution?
something like this
in the TCPsocket.dataavailable event
lock(true)
process lines
lock(false)
which would stop this
method A
lock(true) <- this will stop untill the above in “unlocked”
process lines
lock(false)
I am currently looking at CriticalSection however it mentions a lot about threads beut nothing about TCPsockets.
All help appreciated.
I can test it myself however it will take a few hours to re-code the program so hoping for a “YES it will work” or “wasting your time - try this”
Maybe a global timer to check if thread or the specific timers is running and add there the listbox.enable.
Or enumerator with running and complete and then execute the enable disable?
And i thing is on TCPsocket.datacomplete No dataavailable event.
For me work perfect when i use shell’s.
I don’t think you should use a Listbox as data store. It’s just Just to display data.
SQLite transactions would be a lot better suited for this. If something else is writing, the rest waits until it’s done. (But it still depends on what you’re doing and how.)
In your ListBox solution, if you make ‘Lock’ a global property, you’re getting close but you can still get race conditions.
Uh, no. That is not possible in Xojo, unless you are calling DoEvents somewhere, which is a bad thing indeed. Xojo is single-core, cooperative thread. What you describe is not possible unless you are doing something wrong.
I dont know if you update or add rows,but if you add rows one more solution is to count the rows,with listcount?
if listbox1.listcount >100 then
add your code here
end if
If your RowTag is free put there a true, when the row is free or false when the row is on write!!
All is just ideas to think
the reason i am using the listbox is that it holds 8 columns of data which I use .
similar to this
lock(true)
use row 14 to process the data - each value in the row is used depending on if it is a tcp to method or timer.
lock(false)
if the lock doesn’t work then the other one which slips through processes the data on lines 17
once row 14 finished row 14 is deleted
so row 17 is now row 16 but row 17 is deleted and (to make it worse) row 16 (old row 17) is processed a second time.
[quote=257392:@damon pillinger]HI Guys,
I have an app which uses threads AND TCPsockets and methods.
All of these can read and write to a listbox
I have tried several ways to lock the listbox while it is being updated by a EasyTCPsocket so the methods and Threads cant use it.[/quote]
The simplest way I can think of is to use a CanModify as Boolean.
When a thread or socket wants to write, it checks if CanModify is true, sets it false, proceeds, and then set it back to true.
The inconvenient is that you need to wait until it is true again in each socket or thread.
The other method is to use a queue (array) of modifications to do that will be executed until it is empty. So it takes no time. But that means creating a language of instructions in order to update your ListBox. I shall think something like Cell row, column is fairly easy to parse and would suffice. Then each method/socket event/thread only updates the queue which takes no time, and a single method updates the ListBox line by line and removes it whenever the queue is not empty.
I think a complete redesign of your Framework is needed and i would go the SQLite Database way. Read/Write your Data into a SQLite Database. Queue Up the writing so that 2 Threads/Timers will never write at the same time and display in more or less regular intervals your ListBox by reading the current Information from the SQLite Database.
This way you can much faster and more reliable read/write the Data and make the ListBox independent just displaying the Data.
[quote=257410:@damon pillinger]if the lock doesn’t work then the other one which slips through processes the data on lines 17
once row 14 finished row 14 is deleted
so row 17 is now row 16 but row 17 is deleted and (to make it worse) row 16 (old row 17) is processed a second time.[/quote]
This looks like a recipe for disaster. You may want to uncouple data and presentation.
No need to Queue the writing. SQLite is transactional/acid compliant.
The build-in locking mechanism handles that. The driver (should) handle(s) the waiting for the lock to become free.