[solved] GetGadgetText() problem inside a thread

Just starting out? Need help? Post your questions and find answers here.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4991
Joined: Sun Apr 12, 2009 6:27 am

Re: GetGadgetText() problem inside a thread

Post by RASHAD »

@Bernd Hi
I think the problem comes from using GetGadgetText(0) from inside the branch thread
Let the main thread do it's business
Here is another point of view
No KillThread(Thread)

Code: Select all

Global StartTime,Text$

Procedure TestThread(Value)
 
  StartTime = ElapsedMilliseconds()
  While ElapsedMilliseconds() - StartTime < 10000
    Debug 10000 - (ElapsedMilliseconds() - StartTime)
    Debug Text$
  Wend
 
EndProcedure
 

OpenWindow(0, 0, 0, 100, 70, "Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

ButtonGadget(0, 10, 10, 80, 20, "Start Thread")
ButtonGadget(1, 10, 40, 80, 20, "End Thread")

Exit = #False
Repeat
 Text$ = GetGadgetText(0)
  Event = WaitWindowEvent()
 
  Select Event
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 0
          Thread = CreateThread(@TestThread(), 0)
        Case 1
          StartTime = ElapsedMilliseconds() - 9950
          While IsThread(Thread) : Wend
;          While IsThread(Thread) : WaitWindowEvent(1) : Wend
          Debug "End !"
      EndSelect
    Case #PB_Event_CloseWindow
      Exit = #True
  EndSelect
     
Until Exit

Egypt my love
User avatar
Vera
Addict
Addict
Posts: 858
Joined: Tue Aug 11, 2009 1:56 pm
Location: Essen (Germany)

Re: GetGadgetText() problem inside a thread

Post by Vera »

Hi Bernd,

thanks for your hints :)
and yes you're right I first tested the code on Linux where I only saw the massiv delay concerning the main event loop.

On Windows I directly bumbed into your described mischief and really searched long to find the cause or workaround (when using A) ... but didn't.

A: using: While IsThread(Thread) : Wend
STOP always leads to max CPU usage (98%), (or it hangs up)
only once I got [in case this is of help]:
[ERROR] Zeile: 23: [While ElapsedMilliseconds() - StartTime < 10000]
[ERROR] Ungültiger Speicherzugriff. (Schreibfehler an der Adresse 4294967284)[memory access failure]


B: using: While IsThread(Thread) : WaitWindowEvent(1) : Wend
C: not using any While IsThread(Thread)...
STOP will halt the thread, never any hangups

Why do you need IsThread() at all ? (in this example it doesn't seem to matter)
Regarding it's important I found at least the following command sequence with which it will not hang up either:

Code: Select all

If IsThread(Thread) <> 0 : StartTime = ElapsedMilliseconds() - 9950 : EndIf

Code: Select all

Global StartTime

Procedure TestThread(Value)
  
  StartTime = ElapsedMilliseconds()
;  Debug "ST - " + Str(StartTime)
  While ElapsedMilliseconds() - StartTime < 10000
    Debug 10000 - (ElapsedMilliseconds() - StartTime)
    Text$ = GetGadgetText(0)
    Debug Text$ +" - "+ Str(n+1) : n+1
;     Delay(100) ; at least Delay(1) would be good for Linux
  Wend
  
EndProcedure


OpenWindow(0, 0, 0, 100, 70, "Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

ButtonGadget(0, 10, 10, 80, 20, "Start Thread")
ButtonGadget(1, 10, 40, 80, 20, "End Thread")

Exit = #False
Repeat
  
  Event = WaitWindowEvent() ;10 
  
  Select Event
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 0
          Thread = CreateThread(@TestThread(), 0)
        Case 1
         If IsThread(Thread) <> 0 : StartTime = ElapsedMilliseconds() - 9950 : EndIf
 ;         StartTime = ElapsedMilliseconds() - 9950
 ;        While IsThread(Thread) : Wend
 ;        While IsThread(Thread) : WaitWindowEvent(1) : Wend
          Debug "-------- End !"
      EndSelect
    Case #PB_Event_CloseWindow
      Exit = #True
  EndSelect
  
Until Exit 
~~~~~~~~

looks like that meanwhile there are some solutions at hand - so take your choice ;)

greetings ~ Vera
infratec
Always Here
Always Here
Posts: 7662
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: GetGadgetText() problem inside a thread

Post by infratec »

@RASHAD,

thanks for your second version.
The problem is, that my thread does something depending on the text of the Gadget.
I can only avoid this, if I add an additional global variable which holds the text of this Gadget
with LockMutex() and so on.
But I think that's the best crossplatform compatible solution.

@Vera

Your solution works, because it doesn't wait for the end of the thread.
So the main WaitWindowEvent() is called.

But unfortunately I have to wait until the thread is finished todo the next step.
And since there is no event when this happens, I don't know when the thread is finished.
Or I have to add a timer like in an example from ts-soft.

I think I work arround through this problem with using an additional global variable which holds the
actual text of the gadget.

As summary:

Don't use something with Gadgets in an extra thread if it doesn't have an own WindowEvent handler.

Bernd
User avatar
jacdelad
Addict
Addict
Posts: 2032
Joined: Wed Feb 03, 2021 12:46 pm
Location: Riesa

Re: [solved] GetGadgetText() problem inside a thread

Post by jacdelad »

I'm currently stumbling across some things that were discussed many years before. Like this here. Basically: I cannot use GetGadgetText/GetGadgetState within a thread. This thread clearly points this out and I already wrote a workaround for my usecase. But this leaves a question to me: Why? Is there any special reason why this does not work? It prevents my RibbonGadget from being updated within a thread. So I now need a workaround which gives the programmer a bit more work.
Good morning, that's a nice tnetennba!

PureBasic 6.21/Windows 11 x64/Ryzen 7900X/32GB RAM/3TB SSD
Synology DS1821+/DX517, 130.9TB+50.8TB+2TB SSD
BarryG
Addict
Addict
Posts: 4219
Joined: Thu Apr 18, 2019 8:17 am

Re: [solved] GetGadgetText() problem inside a thread

Post by BarryG »

jacdelad wrote: Fri Mar 08, 2024 5:23 amIs there any special reason why this does not work?
It's due to it not supported on Linux/Mac, so the Windows version has to deny it as well.
User avatar
Caronte3D
Addict
Addict
Posts: 1371
Joined: Fri Jan 22, 2016 5:33 pm
Location: Some Universe

Re: [solved] GetGadgetText() problem inside a thread

Post by Caronte3D »

When strictly necessary for me, I use global variables in the gadget id (PB_Any) and lock with Mutex while accessing gadgets from threads. It's not good practice to delay the main loop if you block for a long time, but... at least it works for me as a last resort.
User avatar
mk-soft
Always Here
Always Here
Posts: 6320
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: [solved] GetGadgetText() problem inside a thread

Post by mk-soft »

Reading gadgets from threads is not a problem, but writing is.
Solution see signature ThreadToGUI
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
jacdelad
Addict
Addict
Posts: 2032
Joined: Wed Feb 03, 2021 12:46 pm
Location: Riesa

Re: [solved] GetGadgetText() problem inside a thread

Post by jacdelad »

That's why I'm confused, GetGadgetState and GetGadgetText obviously read the gadget.
Good morning, that's a nice tnetennba!

PureBasic 6.21/Windows 11 x64/Ryzen 7900X/32GB RAM/3TB SSD
Synology DS1821+/DX517, 130.9TB+50.8TB+2TB SSD
User avatar
mk-soft
Always Here
Always Here
Posts: 6320
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: [solved] GetGadgetText() problem inside a thread

Post by mk-soft »

Have you activated the compiler option thread safe ?
That is very important ...
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
jacdelad
Addict
Addict
Posts: 2032
Joined: Wed Feb 03, 2021 12:46 pm
Location: Riesa

Re: [solved] GetGadgetText() problem inside a thread

Post by jacdelad »

Yes, yes.
For now I don't use the function in the thread, but send a custom event afterwards which is handled in the main loop.
When I'm back at work, in some hours, I'll try to use BindGadgetEvent and handle it in a separate function. This way the ribbon does not need to access the gadget when retrieving the text and the text is stored in a variable, when it's changed. Should work.
Good morning, that's a nice tnetennba!

PureBasic 6.21/Windows 11 x64/Ryzen 7900X/32GB RAM/3TB SSD
Synology DS1821+/DX517, 130.9TB+50.8TB+2TB SSD
Post Reply