[solved] GetGadgetText() problem inside a thread

Just starting out? Need help? Post your questions and find answers here.
infratec
Always Here
Always Here
Posts: 7662
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

[solved] GetGadgetText() problem inside a thread

Post by infratec »

Hi,

I created a program with threads.
Inside one thread I use GetGadgetText().
Only the main program has an event loop.

Now when I try to wait for the end of the thread inside of my main event loop with

Code: Select all

While IsThread() : wend
the program is blocked.
I discovered that GetGadgetText() is guilty.

To avoid the blocking I'm using now

Code: Select all

While IsThread() : WaitWindowEvent(1) : Wend
It works.

Is there a better solution?
Or where in the help is written that GetGadgetText() is only working when WindowEvent() is called?

Bernd
Last edited by infratec on Tue Apr 19, 2011 9:21 am, edited 1 time in total.
c4s
Addict
Addict
Posts: 1981
Joined: Thu Nov 01, 2007 5:37 pm
Location: Germany

Re: GetGadgetText() problem inside a thread

Post by c4s »

Maybe WaitThread() or While IsThread() : Delay(10) : Wend works?
If any of you native English speakers have any suggestions for the above text, please let me know (via PM). Thanks!
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 »

A small example

Code: Select all

Global StartTime

Procedure TestThread(Value)
  
  StartTime = ElapsedMilliseconds()
  While ElapsedMilliseconds() - StartTime < 10000
    Debug 10000 - (ElapsedMilliseconds() - StartTime)
    Text$ = GetGadgetText(0)
  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()
  
  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
If you press 'Start' you have 10 seconds time to 'End' the thread.
It is blocked.
To make it work, you have to comment the first while and discomment the second one.

Bernd
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 »

c4s wrote:Maybe WaitThread() or While IsThread() : Delay(10) : Wend works?
Delay changes nothing :cry:
I already tested this.

I'll test WaitThread().

It is also not working (as expected).
Because the problem has nothing todo with the Thread-Functions.

Bernd
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Re: GetGadgetText() problem inside a thread

Post by ts-soft »

Code: Select all

Global StartTime

Procedure TestThread(Value)
 
  StartTime = ElapsedMilliseconds()
  While ElapsedMilliseconds() - StartTime < 10000
    Debug 10000 - (ElapsedMilliseconds() - StartTime)
    Text$ = GetGadgetText(0)
  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()
 
  Select Event
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 0
          Thread = CreateThread(@TestThread(), 0)
          AddWindowTimer(0, 1, 50)
        Case 1
          StartTime = ElapsedMilliseconds() - 9950
          Debug "End !"
      EndSelect
    Case #PB_Event_Timer
      If Not IsThread(Thread)
         RemoveWindowTimer(0, 1)
        Debug "End !"
      EndIf
    Case #PB_Event_CloseWindow
      Exit = #True
  EndSelect
     
Until Exit 
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
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 »

Hi,

yes, that's a 'safer' solution.
Thanks :!:

But...

It's horrible to implement in my program.
I'll give it a try.

Bernd
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8452
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: GetGadgetText() problem inside a thread

Post by netmaestro »

Your thread has no delay and so it's hogging the whole cpu. This is your main problem. There should be a Delay(1) in your While..Wend loop in the thread.
BERESHEIT
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 »

netmaestro wrote:Your thread has no delay and so it's hogging the whole cpu. This is your main problem. There should be a Delay(1) in your While..Wend loop in the thread.
Hi,

no, this is not my main problem :!:

I know that, but it changes nothing in the behaviour.
Even with a Delay(100), because it has nothing todo with the problem I described.

So it was not very helpfull.

But thanks anyway, maybe this hint is usefull for someone else.

Bernd
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 »

Hello infratec

I added to the while : wend loop: Delay(100)

and enhanced: Event = WaitWindowEvent(10)

and using : While IsThread(Thread) : Wend

This way I can immediately interrupt the thread anytime by stop-command or exit the app.
Just an idea and sorry in case I missed the point.

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 »

Hi Vera,

I don't know If I understand you correct.

I use now:

Code: Select all

Global StartTime

Procedure TestThread(Value)
 
  StartTime = ElapsedMilliseconds()
  While ElapsedMilliseconds() - StartTime < 10000
    Debug 10000 - (ElapsedMilliseconds() - StartTime)
    Text$ = GetGadgetText(0)
    Delay(100)
  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
          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
But it still hangs.

The problem is still the same:

without calling WindowEvent() a GetGadgetText() stucks.

Bernd
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 »

Yes, that's how I meant it.

But I don't get what hangs and why GetGadgetText() should be the cause that blocks your programm. Also a Debug Text$ (inside the thread) will be performed.
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 »

Hi Vera,

I use Windows XP 32bit and PB 4.51.

When I press 'Start Thread' and I see the running down debug time,
and I press than 'Stop Thread' it hangs...

Ok, with your modifications, it can happen that it works.
But if you try it several times you get to a point where it hangs.

Test it.

Why:
When you press 'End Thread' and the thread is inside the Delay() it works.
But when it process the GetGadgetText() it happens.
So I can reduce the probability when I increase the delaytime, but that's not a fix :cry:

Bernd
breeze4me
Enthusiast
Enthusiast
Posts: 633
Joined: Thu Mar 09, 2006 9:24 am
Location: S. Kor

Re: GetGadgetText() problem inside a thread

Post by breeze4me »

Try this.
If the message processing is blocked, the variable(Text$) is empty, but even then, the thread will not be hung.

Code: Select all

Global StartTime

Procedure TestThread(Value)
  Protected Text${256}, result
  
  StartTime = ElapsedMilliseconds()
  While ElapsedMilliseconds() - StartTime < 10000
    Debug 10000 - (ElapsedMilliseconds() - StartTime)
    ;Text$ = GetGadgetText(0)
    SendMessageTimeout_(GadgetID(0), #WM_GETTEXT, 256, @Text$, #SMTO_NORMAL, 800, @result)
    Debug Text$
    Text$ = ""
    Delay(100)
  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
          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
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4991
Joined: Sun Apr 12, 2009 6:27 am

Re: GetGadgetText() problem inside a thread

Post by RASHAD »

Hi Bernd

Code: Select all

Global StartTime

Procedure TestThread(Value)
 
  StartTime = ElapsedMilliseconds()
    
  While (ElapsedMilliseconds() - StartTime) < 10000
    Debug 10000 - (ElapsedMilliseconds() - StartTime)        
    Text$ = GetGadgetText(0)
  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()
 
  Select Event
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 0
          If IsThread(Thread) = 0
            Thread = CreateThread(@TestThread(), 15)
          EndIf
        Case 1
          If IsThread(Thread)
            WaitThread(Thread,25)   ;Tested with Win 7 x64
            KillThread(Thread)
          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

Egypt my love
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 »

@breeze4me

I think: the best solution so far
Only one disadvantage: It uses API stuff.
(But I didn't tetsted yet if it is the same behaviour in Linux)

@RASHAD

The brutal way of life :mrgreen:
A bit better:

Code: Select all

if WaitThread(Thread, 25) = 0
 KillThread(Thread)
endif
But I'm not sure if I can do this, because in my 'real' thread I do some serial stuff,
and I have to leave my buffers in a clean state. That's not possible with KillThread().


Best regards and thanks to all,

Bernd
Post Reply