How to create and use a background task?

Post

Posted
Rating:
#1 (In Topic #1547)
Regular
JumpyVB is in the usergroup ‘Regular’
How to create and use a background task such as something like this? I do want it to raise events too.

Code (gambas)

  1. ' Gambas class file
  2.  
  3.  
  4. Private TmpStr As String = ""
  5.  
  6.   TmpStr = Input
  7.  
  8. Public Sub Main()
  9.   Wait 1000
  10.   TmpStr = "Finished"
  11.  

I was hoping the wiki to have an example here /comp/gb/task - Gambas Documentation but unfortunately it does not have one.
Online now: No Back to the top

Post

Posted
Rating:
#2
Regular
JumpyVB is in the usergroup ‘Regular’
My background task called TestiClass so far:

Code (gambas)

  1. ' Gambas class file
  2. Event TalkBack(Data As String)
  3. Public TmpStr As String = ""
  4.   TmpStr = Input
  5. Public Sub Start()
  6.   Raise TalkBack("Initialized")
  7.   Wait 1
  8.   Raise TalkBack("Progress 20%")
  9.   Wait 1
  10.   Raise TalkBack("Progress 40%")
  11.   Wait 1
  12.   Raise TalkBack("Progress 60%")
  13.   Wait 1
  14.   Raise TalkBack("Progress 80%")
  15.   Wait 1
  16.   TmpStr = "Finished"
  17.   Raise TalkBack("Done")
  18.  

And my FMain so far:

Code (gambas)

  1. ' Gambas class file
  2. Private MyTaskInstance As TestiClass
  3. Public Sub Form_Open()
  4.   MyTaskInstance = New TestiClass("Start Please")
  5.   Object.attach(MyTaskInstance, Me, "TaskWithEvents")
  6. Public Sub Button1_Click()
  7.   Me.Text = MyTaskInstance.TmpStr
  8.   Button1.Enabled = False
  9.   MyTaskInstance.Start()
  10. Private Sub TaskWithEvents_TalkBack(Data As String)
  11.   Button1.Enabled = True
  12.   Me.Text = Data 'This part never seems to run
  13.  

However the events are not being fired on FMain.
Online now: No Back to the top

Post

Posted
Rating:
#3
Guru
BruceSteers is in the usergroup ‘Guru’
You cannot reliably use Task.class like that. (creating events) , you read the wiki?

You must make the task print text output. then in FMain use the tasks Read event.

TestiClass.class

Code (gambas)

  1.  
  2. ' Gambas class file
  3.  
  4. Static Public TmpStr As String = ""
  5.  
  6.   TestiClass.TmpStr = Input
  7.  
  8. Public Sub Main()
  9.   Print "Initialized"
  10.   Wait 1
  11.   Print "Progress 20%"
  12.   ' snip
  13.   TestiClass.TmpStr = "Finished"
  14.   Print "Done"
  15.  
  16.  

FMain.class

Code (gambas)

  1. ' Gambas class file
  2.  
  3. Private MyTaskInstance As TestiClass
  4.  
  5.  
  6. Public Sub Button1_Click()
  7.   Me.Text = TestiClass.TmpStr
  8.   Button1.Enabled = False
  9. '  MyTaskInstance.Start() ' nah, the Main sub is automatically run when a task is created.
  10.  
  11. ' so create it to start it...
  12.   MyTaskInstance = New TestiClass("Start Please") As "TaskWithEvents"
  13.  
  14. ' Note, be careful using Object.Attach as it can steal a classes internal event catching. prefer using Observer.class or just use "As" like i have above.
  15.  
  16.  
  17. ' use Task.class Read event.
  18. Public Sub TaskWithEvents_Read(Data As String)
  19.   Button1.Enabled = True
  20.   Me.Text = Data 'This part never seems to run
  21.  
  22. Public Sub TaskWithEvents_Kill()  ' task ended
  23.  
  24.   Print TestiClass.TmpStr
  25.  
  26.  

Task.class is built only to transmit text data in the read event.
It runs as a completely separate process so you cannot treat it like a normal class in any way. it does not link like a usual application class/module does.
"The Main method is run by a fork. It can access every other part of the program, except that the parent process will not see any change done by the task. "
Online now: No Back to the top

Post

Posted
Rating:
#4
Regular
JumpyVB is in the usergroup ‘Regular’
Thank you for assisting.
Now my FMain.class is this:

Code (gambas)

  1. ' Gambas class file
  2.  
  3. Private MyTaskInstance As TestiClass
  4. Public Sub Button1_Click()
  5.   Me.Text = TestiClass.TmpStr
  6.   Button1.Enabled = False
  7.   MyTaskInstance = New TestiClass("Start Please") As "TaskWithEvents" 'This makes my program crash
  8. Private Sub TaskWithEvents_Read(Data As String)
  9.   Button1.Enabled = True ' This never runs
  10.   Me.Text = Data
  11. Private Sub TaskWithEvents_Kill()  ' Task ended
  12.   Print TestiClass.TmpStr ' This never runs
  13.  
And my TestiClass.class is this:

Code (gambas)

  1. ' Gambas class file
  2.  
  3. Static Public TmpStr As String = ""
  4.   TestiClass.TmpStr = Input
  5. Public Sub Main()
  6.   Print "Initialized"
  7.   Wait 1
  8.   Print "Progress 20%"
  9.   Wait 1
  10.   Print "Progress 40%"
  11.   Wait 1
  12.   Print "Progress 60%"
  13.   Wait 1
  14.   Print "Progress 80%"
  15.   Wait 1
  16.   TestiClass.TmpStr = "Finished"
  17.   Print "Done"
  18.  
However the program will crash as I press Button1 now that the TestiClass.class inherits Task. Am I creating and starting my TestiClass in a wrong fashion?

PS: I'm also willing to learn from and inspect code made by some one else about Task.class in case you could link me to such.
Online now: No Back to the top

Post

Posted
Rating:
#5
Guru
BruceSteers is in the usergroup ‘Guru’
hmm, maybe using Wait in a Task causes problems.

Try Sleep instead.

Ps.  i had not noticed you made the events Private not Public , events never trigger if Private.

Public Sub TaskWithevents_Read(Txt As String)
Online now: No Back to the top

Post

Posted
Rating:
#6
Regular
JumpyVB is in the usergroup ‘Regular’
Thank you so much for your help. Indeed the _Read event had to be Public.

Here's the final code that works for some one else to find and benefit from:

FMain.class:

Code (gambas)

  1. Public MyTaskInstance As TestiClass
  2. Public Sub Button1_Click()
  3.   Button1.Enabled = False
  4.   MyTaskInstance = New TestiClass(["25", "1"]) As "TaskWithEvents"
  5. Public Sub TaskWithEvents_Read(Data As String) 'Print event received from task
  6.   Me.Text = Data
  7. Public Sub TaskWithEvents_Kill() 'Task ended
  8.   Button1.Enabled = True
  9.  

TestiClass.class:

Code (gambas)

  1. Static Private _Arguments As String[]
  2. Public Sub _New(Arguments As String[])
  3.   'Input can only be set here, after that they are read only
  4.   _Arguments = Arguments
  5. Public Sub Main()
  6.   'Parent can observe Prints by subscribing with Read event
  7.   Print "Initialized"
  8.   'Now lets do something slow here and sen progress messages
  9.   Dim Increment As Integer = Val(_Arguments[0])
  10.   Dim Interval As Integer = Val(_Arguments[1])
  11.   For prog As Integer = Increment To 100 - Increment Step Increment'20
  12.     Wait Interval 'Wait seems to work and I didn't need to switch to Sleep
  13.     Print "Progress " & prog & "%"
  14.   Next
  15.   Wait Interval
  16.   'And inform how we are finally done
  17.   Print "Done"
  18.  

There was another problem also. I keep two GNU/Linux operating systems installed and the code above doesn't work on the other one. When code execution on FMain reaches line

Code (gambas)

  1. MyTaskInstance = New TestiClass(["25", "1"]) As "TaskWithEvents"
my program will auto close and return to Gambas with the following error message:

Code

symbol lookup error: /usr/lib64/gambas3/gb.qt6.so: undefined symbol: _ZN18QThreadPoolPrivate13qtGuiInstanceEv, version Qt_6_PRIVATE_API
Any idea how to investigate and troubleshoot this? Is there a way to enforce Gambas not to use Qt 6 in any way but only Qt 5 only?

I tried a few methods do disable Qt 6 but they did not work: If I right click the Gambas dot-desktop icon and select "Run with QT 5" I still get the Qt_6 error. Same if I recompile Gambas with

Code

$ ./configure -C --disable-qt6
. Qt 6 will still somehow get to the end product.
Online now: No Back to the top

Post

Posted
Rating:
#7
Avatar
Administrator
gbWilly is in the usergroup ‘unknown’

JumpyVB said

There was another problem also. I keep two GNU/Linux operating systems installed and the code above doesn't work on the other one. When code execution on FMain reaches line

Code (gambas)

  1. MyTaskInstance = New TestiClass(["25", "1"]) As "TaskWithEvents"
my program will auto close and return to Gambas with the following error message:

Code

symbol lookup error: /usr/lib64/gambas3/gb.qt6.so: undefined symbol: _ZN18QThreadPoolPrivate13qtGuiInstanceEv, version Qt_6_PRIVATE_API
Any idea how to investigate and troubleshoot this?

I tried a few methods do disable Qt 6 but they did not work: If I right click the Gambas dot-desktop icon and select "Run with QT 5" I still get the Qt_6 error. Same if I recompile Gambas with

Code

$ ./configure -C --disable-qt6
. Qt 6 will still somehow get to the end product.
What system are you running where it works and what system where it doesn't?
Does the distro only provide qt6 and no more qt5?
Could you post the system info of both systems (in IDE menu ? -> System Info)

You might have a too new qt6 version as it seems not to support some symbol call
If I remember correctly there have been post on mailing list several times in recent past of systems breaking Gambas (mainly rolling releases like Arch), because of newer qt6 libraries. I guess this might be something like that.

So, detailed info is needed to compare library version (hence the system info). If this is the case it should be reported on bugtracker, so Benoit can have a look at it.

JumpyVB said

 Is there a way to enforce Gambas not to use Qt 6 in any way but only Qt 5 only?
If in IDE go to Project -> Properties  -> Tab Component to set your project to qt5.
Image

(Click to enlarge)

I never use the general gui, gui.qt or gui.gtk3 components in a project but always select the component I want my application to use (in my case always qt5).
I even made a template so my application can be newly created with qt5 instead of having to choose the general qt application that gives me gb.gui.qt instead of gb.qt5.

Hope this helps…

gbWilly
- Gambas Dutch translator
- Gambas wiki content contributor
- Gambas debian/ubuntu package recipe contributor
- GambOS, a distro for learning Gambas and more…
- Gambas3 Debian/Ubuntu repositories


… there is always a Catch if things go wrong!
Online now: No Back to the top

Post

Posted
Rating:
#8
Regular
JumpyVB is in the usergroup ‘Regular’
- The issue is present in Solus.
- The code works in Open Suse Tumbleweed.
- I have been using the default gb.gui component.
- I just tried replacing gb.gui with gb.qt5 and the code now runs as it should.
- I confirm my issue is solved now. Thank you so much for helping me.
Online now: No Back to the top

Post

Posted
Rating:
#9
Avatar
Administrator
gbWilly is in the usergroup ‘unknown’

JumpyVB said

- I just tried replacing gb.gui with gb.qt5 and the code now runs as it should.
- I confirm my issue is solved now. Thank you so much for helping me.

Good you have it working now. Glad I could help.
Enjoy…

gbWilly
- Gambas Dutch translator
- Gambas wiki content contributor
- Gambas debian/ubuntu package recipe contributor
- GambOS, a distro for learning Gambas and more…
- Gambas3 Debian/Ubuntu repositories


… there is always a Catch if things go wrong!
Online now: No Back to the top
1 guest and 0 members have just viewed this.