Gambas France BETA

Connexion

Pas de compte ? Incription

Exemple 29 :

Utilisation de Task, dans un Splash Screen :


Les déclarations, dans le formulaire, FSplash :


1
2
PRIVATE $iCount AS INTEGER
PRIVATE $hTask AS CSplash '<--------' la Tâche elle même

Le code, du Splash :


1
2
3
4
5
6
7
PUBLIC SUB Form_Open()

TaskRun() '<--------' Lancement de la tâche par son instanciation
$iCount = 0
Timer1.Start

END
Procédure de démarrage de la Tâche :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
PRIVATE SUB TaskRun() '<--------' définition de la procédure pour instancier la tâche

IF $hTask = NULL THEN $hTask = NEW CSplash AS ("Splash")

REPEAT
WAIT 0.001
UNTIL $hTask <> NULL

Application.Priority = 10 '<--------' définition de la priorité

' Label2.Text = ("Tâche") & " = " & "[ " & $hTask.Value & " ] [ " & "PID = " & Str($hTask.Handle) & " ]" & " [ " & Str($hTask.Running) & " ]"
'Si placé, ici, la Task.Running est True mais je n'ai pas le renvoi de la date dans la Task.Value

END
Ce qu'on récupère à la fin de la tâche :
1
2
3
4
5
6
PUBLIC SUB Splash_Kill()

Label2.Text = ("Tâche" & " = " & "[ " & $hTask.Value & " ] [ " & "PID = " & Str($hTask.Handle) & " ]" & " [ " & Str($hTask.Running) & " ]" ' $hTask.Wait
'Si placé, ici, la Task.Running est False mais j'ai le renvoi de la date dans la Task.value.

END
Le Timer pour faire défiler le progressBar :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
PUBLIC SUB Timer1_Timer()

ProgressBar1.Visible = TRUE
INC $iCount
ProgressBar1.value = $iCount / MVar.iTemp

IF MVar.bsortie THEN
Label1.Caption = ("Patientez, déchargement en cours..."
ProgressBar1.Direction = 2 '<------------------------' droite à gauche
ELSE
Label1.Caption = ("Patientez, chargement en cours...")
ProgressBar1.Direction = 1 '<------------------------' gauche à droite
ENDIF

'Label2.Text = ("Tâche") & " = " & "[ " & $hTask.Value & " ] [ " & "PID = " & Str($hTask.Handle) & " ]" & " [ " & Str($hTask.Running) & " ]"
'Si placé, ici, la Task.Running est False mais j'ai le renvoi de la date dans la Task.value.

IF $iCount = MVar.iTemp THEN
MSon.son("beep")
WAIT 0.25 '<--------' durée exacte du son
ME.Close()
ENDIF

END

Une image pour comprendre ce que sont ces labels :



En action :



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
PUBLIC SUB Form_Close()

Timer1.Stop
Timer1 = NULL
ProgressBar1 = NULL
Label1 = NULL

IF $htask THEN
IF $hTask.Running THEN
$hTask.Stop
$hTask.Wait
ENDIF
$hTask = NULL
ENDIF

FSplash.Delete()

END

La Classe CSplash pour déclarer la Task :


1
2
3
4
5
6
7
8
9
10
11
12
' Gambas class file

INHERITS Task '<--------' héritage de Task

PUBLIC SUB Main() AS STRING '<--------' sub Main obligatoire même, vide

DIM saListeJours AS String[]

saListeJours = Split(("Dimanche,Lundi,Mardi,Mercredi,Jeudi,Vendredi,Samedi"), ",")
RETURN saListeJours[WeekDay(Now())] & " " & Day(Now) & "/" & Format(Month(Now), "00") & "/" & Year(Now) '<--------' ce que je récupère grâce à la tâche

END


Commentaires :


Ici, j'ai effectué un détournement de Task qui n'a pas grand intérêt, si ce n'est pédagogique.
Vous trouverez dans les exemples, l'utilisation des propriétés et des évènements de Task.
Task ne devrait être utilisé que quand la charge d'une tâche est importante pour ne pas bloquer le programme principal.

Voir la documentation : https://gambaswiki.org/wiki/comp/gb/task

Et les quelques exemples, rares, d'utilisation sur la logithèque, dont je me suis inspiré :



Et ce que j'en ai fait


Un lien vers un exemple pratique de la forge : LMClass


Commentaires d'Olivier :


En ce qui concerne les TASK dans Gambas, cela ne sert pas pour tous les cas, mais typiquement lorsqu’on veut faire du travail en tâches parallèles, les TASK sont là pour ça, genre gros calculs ou traitements, que l’on puisse segmenter bien sûr.

Mais si c’est pour faire juste un petit travail, souvent la machine est assez rapide pour que cela soit transparent pour l’utilisateur.

Un exemple qui ne nécessite pas de TASK qui donne l’impression de se faire en tache de fond :

1ere méthode basique:


exécuter une commande ’SHELL’
Basiquement, ’SHELL <ma commande qui prend du temps> WAIT
Le pb ici c’est que toute l’interface du programme va se figer jusqu’à la fin de la commande SHELL

2eme méthode:


exécuter une commande “SHELL” mais au travers d’un object Process
NomProcess = SHELL “ma commande qui prend du temps> AS “monEvenementProcess”

1
2
3
PUBLIC SUB monEvenementProcess_Read(Data AS STRING)

END
1
2
3
PUBLIC SUB monEvenementProcess_Kill()

END
1
2
3
PUBLIC SUB monEvenementProcess_Error(ERROR AS STRING)

END


Donc ici l’interface n’est pas figée et dès qu’un événement monte, READ, KILL, ERROR, on traite les données à la volée et tout est transparent pour l’utilisateur, il a l’impression que cela s’exécute en tâche de fond.


3eme méthode,


un peu similaire à la 2eme, à la différence que l’on exécute la commande SHELL dans une TASK, donc réellement en parallèle du process principal de l’interface ou projet, mais c’est plus lourd à mettre en place.
En cas de très forte charge de la machine, si de multiples TASK sont lancées, alors il peut y avoir des pertes de TASK dans le sens où la TASK se termine mais que le process principal de l’application ne soit pas au courant, etc….


====================

Navigation :



<-- Liens du Wiki : <--
<-- Accueil du WIKI : <--

====================

La Documentation :



====================