Page 2 of 2
Re: GetGadgetText() problem inside a thread
Posted: Mon Apr 18, 2011 9:05 pm
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
Re: GetGadgetText() problem inside a thread
Posted: Mon Apr 18, 2011 11:00 pm
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
Re: GetGadgetText() problem inside a thread
Posted: Tue Apr 19, 2011 9:21 am
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
Re: [solved] GetGadgetText() problem inside a thread
Posted: Fri Mar 08, 2024 5:23 am
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.
Re: [solved] GetGadgetText() problem inside a thread
Posted: Fri Mar 08, 2024 6:38 am
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.
Re: [solved] GetGadgetText() problem inside a thread
Posted: Fri Mar 08, 2024 1:42 pm
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.
Re: [solved] GetGadgetText() problem inside a thread
Posted: Fri Mar 08, 2024 2:02 pm
by mk-soft
Reading gadgets from threads is not a problem, but writing is.
Solution see signature ThreadToGUI
Re: [solved] GetGadgetText() problem inside a thread
Posted: Fri Mar 08, 2024 6:14 pm
by jacdelad
That's why I'm confused, GetGadgetState and GetGadgetText obviously read the gadget.
Re: [solved] GetGadgetText() problem inside a thread
Posted: Fri Mar 08, 2024 6:41 pm
by mk-soft
Have you activated the compiler option thread safe ?
That is very important ...
Re: [solved] GetGadgetText() problem inside a thread
Posted: Fri Mar 08, 2024 7:09 pm
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.