Page 1 of 2

Controls "Blanking Out" [False Alarm by Noob]

Posted: Thu Mar 23, 2017 3:22 pm
by PB2004
My 20,000-line program has a tabbed interface. On the first tab, a selected file is processed when a button is hit. A lot of processing then happens - many structures created, populated and sorted, files read and written etc. When this processing starts, all the buttons on this tab disappear and the contents of a couple of listview gadgets go blank. When finished several seconds later, everything reappears. I am reminded of a drunk, eyes rolling back in his head before he passes out. Very unprofessional looking to say the least...

I've tried to reproduce this behavior in a 50-line example to share with the forum but can't produce the blanking. Not a ripple.

So I am just soliciting ideas at this point. What resource am I overtaxing? Is there some command that will freeze the GUI while processing is going on? Have you ever experienced this and how did you solve it? Thanks in advance.

[edit] Just skip to my last post for the root cause....

Re: Controls "Blanking Out" or Disappearing

Posted: Thu Mar 23, 2017 3:41 pm
by Fig
During your long processing, do you take care of the events ?

Re: Controls "Blanking Out" or Disappearing

Posted: Thu Mar 23, 2017 6:35 pm
by netmaestro
At first blush it sounds like you are probably doing too much heavy processing in the main loop, which will interfere with the timely processing of window events. Look at offloading some of it to threads. The use of BindEvent or BindGadgetEvent will do this for you automatically, so that's a good place to start.

Re: Controls "Blanking Out" or Disappearing

Posted: Thu Mar 23, 2017 7:00 pm
by PB2004
I use a single loop of this form:

Code: Select all

  Repeat
    
    event = WaitWindowEvent()
    
    Select event
        
      Case #PB_Event_CloseWindow
        Select EventWindow()
          Case #Window_mainForm
            quitmainForm=1
        EndSelect
        
      Case #PB_Event_Gadget
        Select EventGadget()
          Case #do_btn
            Select EventType()
              Case #PB_EventType_LeftClick
                do_lotta_stuff()
            EndSelect
        EndSelect  ;EventGadget()
        
    EndSelect  ;event
    
    
  Until quitmainForm
I change the contents of one of the listboxes at the very end of the procedure, but this is only refreshing a few items in the box.

Re: Controls "Blanking Out" or Disappearing

Posted: Fri Mar 24, 2017 4:08 am
by PB2004
Thanks for the suggestions. Using BindEventGadget() did not change anything, though it was a good refresher for me. I looked again. There is some light controls loading in this procedure. So I commented out any line that affected the state of a control but still get the blanking. ~40 visible controls - the panelgadget, Buttons, text gadgets, stringgadgets, comboboxgadgets and listviewgadgets all disappear. Only the window title bar and the outlines of the listviewgadgets persist. The blanking duration pretty much matches the duration of the procedure, ~3 seconds. Starting up, my window loads in a small fraction of a second. It is not fatal but looks like it is taking a malware hit and will probably terrify any user....

Is there any way to temporarily "freeze" the update of my window?

Re: Controls "Blanking Out" or Disappearing

Posted: Fri Mar 24, 2017 6:19 am
by Keya
another thing could be conflict with gadget IDs, shouldnt be a problem if youre assigning them all within an Enumeration or using #PB_Any though but maybe there's a rogue line of code calling DoGadgetSomething(wrongid,...)
PB2004 wrote:The blanking duration pretty much matches the duration of the procedure, ~3 seconds.
but when you said that to me i wonder if it just means you should be doing that activity in a separate thread to allow the GUI to refresh

Re: Controls "Blanking Out" or Disappearing

Posted: Fri Mar 24, 2017 7:57 am
by infratec
Hi,

without knowing your program...

Meassure the time of do_lotta_stuff()
I'm sure it takes around 3s :wink:

To avoid a blocking GUI, you need a thread which do your lotta stuff.

Bernd

Re: Controls "Blanking Out" or Disappearing

Posted: Fri Mar 24, 2017 10:06 am
by Fig
I suggest, in your LotsOfStuff's loops to treat your events to make them disappear from the queue event. (just insert WindowsEvent() or an inner loop processing all the WindowsEvent() as shown in the help)
When your queue is not process during few seconds, your program looks stuck and the gui stop refreshing.

Code: Select all

  Repeat
    event = WaitWindowEvent()
    Select event
        Case #PB_Event_CloseWindow
        Select EventWindow()
          Case #Window_mainForm
            quitmainForm=1
        EndSelect
        
      Case #PB_Event_Gadget
        Select EventGadget()
          Case #do_btn
            Select EventType()
              Case #PB_EventType_LeftClick
                For x
                WindowEvent()
                Do_stuffs
               next x
               For y
               WindowsEvent()
               Do_Other_Stuff
               next y
            EndSelect
        EndSelect  ;EventGadget()
        
    EndSelect  ;event
    
    
  Until quitmainForm


As it was said, an another solution is to thread your procedure.

Re: Controls "Blanking Out" or Disappearing

Posted: Fri Mar 24, 2017 10:18 am
by infratec
Never use more than one event loop.

Only one place in the whole program which reacts on events.
Else you run into trouble. Trust me.

Bernd

Re: Controls "Blanking Out" or Disappearing

Posted: Fri Mar 24, 2017 10:19 am
by netmaestro
infratec wrote:Only one place in the whole program which reacts on events.
Else you run into trouble. Trust me.
Trust him. I do.

Re: Controls "Blanking Out" or Disappearing

Posted: Fri Mar 24, 2017 10:20 am
by Fig
You don't have to react to the event (we dont' care what's happening during the long time of processing), just to discard them from the queue to show activity, else the program will get stuck.
It has no bad effect on the program and it's much more simpler than using a thread.

Re: Controls "Blanking Out" or Disappearing

Posted: Fri Mar 24, 2017 10:23 am
by infratec
Fig wrote:You don't have to react to the event (we dont' care what's happen during the long time of processing), just to discard them form the queue, else the program will get stuck.
It has no bad effect on the program.
Ah..., you loosing events withoput knowing which ones.
No good idea.

Re: Controls "Blanking Out" or Disappearing

Posted: Fri Mar 24, 2017 10:24 am
by netmaestro
You don't have to check the value of the event, just to discard them form the queue
Discard them, with no thought to whether they're important or not? Seriously? Use one eventloop which responds to all relevant cases and offload any timeconsuming processing to a thread. That's the way forward, not this convoluted (I said 'convoluted' but I could be reasonably accused of meaning 'stupid') nonsense. (OK, guilty as charged. Take me to the guy with the noose.)

Re: Controls "Blanking Out" or Disappearing

Posted: Fri Mar 24, 2017 10:25 am
by Fig
OK, let's remember the question:
It is not "how to make the time to process lotsofstuff imperceptible" but "how to make the gui stop blanking while it's processing."

During long seconds of processing lotsofstuff, your program can react to no event.
So what's the point to keep track of them anyway ? At best the user will try to make the program closed thinking it's stuck.
We better ignore these attempts and display a windows to inform user, it will take some time...

What kind of event() would be so critical ? Are they sacred objects of a new religion ?

Anyway, he can try discarding event and see if it's ok for users (as far as it will not mess with the program and he think events are not important while it's processing)
If not, he will use a thread.

I recognize this is not the by the book solution. But who care ?
And for the record, i am obviously stupid. 8)

Re: Controls "Blanking Out" or Disappearing

Posted: Fri Mar 24, 2017 4:13 pm
by PB2004
Wow. If I were a troll I could not be more pleased with the attention this is getting from our esteemed forum heavyweights and Bullfrogs!

A few thoughts. Infratec and NetMaestro schooled this tadpole http://www.purebasic.fr/english/viewtop ... 13&t=65424 right after I emerged from my egg sac. I thought I'd never have to worry about events again.

Like I said, I did substitute the bindgadgetevent approach as suggested by NetMaestro. The program ran great but this had no effect on the blanking. NetMaestro says that this is the equivalent of a thread. If true (I am not doubting, I am just wriggling dangerously in a deeper part of the pond than I am used to) then why bother with a threaded approach?

All my gadgets are numbered with the [edit] enumerated constants method so ID collisions are doubtful. I will double-check but have seen no evidence of gadget confusion.

[edit] I should mention that the user is not expected to do anything while this processing is going on.

Here is my code to try to replicate the behavior:

Code: Select all

Enumeration
  
  #Window_mainForm
  #do_btn
  #listview1
  #listview2
  
EndEnumeration

EnableExplicit

Procedure.i Window_mainForm()

  If OpenWindow(#Window_mainForm,0,0,600,600,"Test  Blankout",#PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_ScreenCentered)
    
    
    ButtonGadget(#do_btn,450,15,90,30,"Do Something")

    ListViewGadget(#listview1,10,10,400,280)

    ListViewGadget(#listview2,10,300,400,280)
    
    ProcedureReturn 1 
    
 
  EndIf
EndProcedure  ;Window_mainForm()


Procedure load_listview()
  AddGadgetItem(#listview1, -1, "item 0")
  AddGadgetItem(#listview1, -1, "item 1")
  AddGadgetItem(#listview1, -1, "item 2")
  AddGadgetItem(#listview1, -1, "item 3")
  AddGadgetItem(#listview1, -1, "item 4")
  AddGadgetItem(#listview1, -1, "item 5")
  AddGadgetItem(#listview1, -1, "item 6")
  AddGadgetItem(#listview1, -1, "item 7")
  
  AddGadgetItem(#listview2, -1, "item 0")
  AddGadgetItem(#listview2, -1, "item 1")
  AddGadgetItem(#listview2, -1, "item 2")
  AddGadgetItem(#listview2, -1, "item 3")
  AddGadgetItem(#listview2, -1, "item 4")
  AddGadgetItem(#listview2, -1, "item 5")
  AddGadgetItem(#listview2, -1, "item 6")
  AddGadgetItem(#listview2, -1, "item 7")
  
EndProcedure


Procedure do_something()
  Protected i, j.f, k.f, size, iterations
  
  size = 2*1000*1000*100   ;  ~10 seconds to process
  iterations = 1
  
  Dim testarray.f(size)
  
  For i = 1 To iterations
    
;     CreateFile(1,"erase_me.txt")
;     WriteStringN(1, "a line of text")
;     CloseFile(1)
;     DeleteFile("erase_me.txt")
    
    j = i
    k = j / 0.5347
    testarray(i) = k
    SortArray(testarray(),#PB_Sort_Descending)
  Next i
  
  MessageRequester("","Done")
   
EndProcedure


Define event
Define quitmainForm=0
Define windowOpened


windowOpened = Window_mainForm()  

If windowOpened 
  
  load_listview()
  
  Repeat
    
    event = WaitWindowEvent()
    Select event
        
      Case #PB_Event_CloseWindow
        Select EventWindow()
          Case #Window_mainForm
            quitmainForm=1
        EndSelect
        
      Case #PB_Event_Gadget
        Select EventGadget()
          Case #do_btn
            Select EventType()
              Case #PB_EventType_LeftClick
                do_something()
            EndSelect
        EndSelect  ;EventGadget()
        
    EndSelect  ;event

  Until quitmainForm
  CloseWindow(#Window_mainForm)  

EndIf ;windowOpened
I thought I could make this choke and blank but I can't. If someone else can, then we could truly see which approach(es) will fix the problem.

Thanks again for all your inputs.