[Gambas-user] App idle with long loops

Jorge Carrión shordi at ...626...
Sun Oct 9 19:07:20 CEST 2016


Thanks to every one for the information. I think I have enough to make my
proyect more usable.

Best Regards



2016-10-09 18:40 GMT+02:00 Tobias Boege <taboege at ...626...>:

> On Sun, 09 Oct 2016, Jorge Carrión wrote:
> > 2016-10-08 23:54 GMT+02:00 Demosthenes Koptsis <demosthenesk at ...626...>:
> >
> > > On 8/10/2016 19:09 μμ, Tobias Boege wrote:
> > > > On Sat, 08 Oct 2016, Demosthenes Koptsis wrote:
> > > >> Hello,
> > > >>
> > > >> i have very long (time consuming) For loops and my app is frozen
> until
> > > >> loop is finished.
> > > >>
> > > >> for example i wget urls with a custom Sub which
> Shell("wgetURLS.sh") To
> > > >> sOUTPUT
> > > >>
> > > >>     'get urls
> > > >>     For i = 0 To iDepth
> > > >>       wgetURLS(i * 10)
> > > >>     Next
> > > >>
> > > >> Public Sub wgetURLS(iStart As Integer)
> > > >> .....
> > > >>
> > > >> Shell("wgetURLS.sh") To sOUTPUT
> > > >>
> > > >> .....
> > > >>
> > > >> --------------
> > > >>
> > > >> Is there possible to set the gui idle and the same time run
> For...loops?
> > > >>
> > > > If you only want to refresh the GUI (e.g. if your For loops update a
> > > > ProgressBar on your form and you want to update the value of that bar
> > > > during the loop), then Wait [1] is sufficient.
> > > >
> > > > If you want the GUI to be fully operatable while your loops run in
> the
> > > > background, you have to use a background Task [2]. As Gambas is
> single-
> > > > threaded, Tasks are implemented as external processes which execute
> one
> > > > of your classes. This limits the things you can do with Tasks (you
> cannot
> > > > directly modify the main program, for example, but have to send data
> and
> > > > status reports through a pipe from your Task to the main process and
> > > > interpret them there). However, if all you want is loading some
> files via
> > > > wget, that should not be a problem.
> > > >
> > > > Of course, there is also the gb.net.curl component which can download
> > > files
> > > > asynchronously. If you can use that (which depends on what you want
> to
> > > do),
> > > > you should.
> > > >
> > > > And as a fourth option, looking further into your code: if you want
> to
> > > > execute shell scripts in a For loop, then don't use the Shell-To
> syntax
> > > > but create a Process object instead and accumulate its output in Read
> > > > events. The event loop will take care of everything and the GUI will
> be
> > > > usable without any extra effort on your side.
> > > >
> > > > Finding the best solution depends, who would have thought, on what
> you
> > > want
> > > > to do *specifically*. Tasks are the most general and most cumbersome
> > > option.
> > > >
> > > > Regards,
> > > > Tobi
> > > >
> > > > [1] http://gambaswiki.org/wiki/lang/wait
> > > > [2] http://gambaswiki.org/wiki/comp/gb/task
> > > >
> > > Thanks very much for the details.
> > >
> > > Regards,
> > >
> > > Dim
> > >
> > >
> > Is there any example of task fork use? I have a proyect who sending
> massive
> > e-mails to our customers and I guess that task can be a good solution...
> >
> > Regards
> >
>
> It normally works like this:
>
>   - You write a dedicated class, let's call it MyTask, to perform your
> task.
>     This class must inherit the Task class.
>   - The constructor of MyTask can receive some arguments for the task, like
>     an array of recipient addresses and bodies for your batch email.
>   - After the MyTask object is created, the process fork is postponed to
> the
>     next invocation of the event loop. You may want to keep this in mind if
>     you sometimes start a whole bunch of tasks at once or if you want to
>     wait for the results of your task in the current procedure. To have the
>     tasks started, you either have to enter the event loop, either by
>     rolling up the current code path or by calling Wait.
>   - The interpreter will then fork and jump into the Main() method of the
>     MyTask object. The standard output of the new process running the Task
>     is redirected into the main program and raises Read events of the Task
>     object. You can also return serialisable data from the Main() method
>     which is transferred into the main process and which you can fetch
> these
>     using MyTask.Value.
>   - Because returning a single value at the end of the task may not be
>     sufficient, you normally end up using the standard output to
> communicate
>     more regularly with the main process. I could imagine that you want to
>     send messages of the form:
>
>         "sent\tx\tn"
>
>     to your main process, indicating that you just sent the x-th email of
>     n emails total. The main process intercepts this string, has to parse
> it
>     and can then update a ProcessBar or something. This is the way I use
>     Tasks in my projects, anyway.
>
> An example can also be found in the gb.form component. The FileView class
> uses a background task named CTaskPreview to make preview of images in the
> background and send them to the main process once they're ready.
>
> Regards,
> Tobi
>
> --
> "There's an old saying: Don't change anything... ever!" -- Mr. Monk
>
> ------------------------------------------------------------
> ------------------
> Check out the vibrant tech community on one of the world's most
> engaging tech sites, SlashDot.org! http://sdm.link/slashdot
> _______________________________________________
> Gambas-user mailing list
> Gambas-user at lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/gambas-user
>



More information about the User mailing list