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/taskEt les quelques exemples, rares, d'utilisation sur la logithèque, dont je me suis inspiré :
- TaskValue 0.2.1 (Hans Lehmann)
- TaskExample 0.1.1 (Cogier)(Charlie Ogier)
- InFile 1.0.1 (Cogier)(Charlie Ogier)
- taskpipe 0.0.3 (LinuxOS)(OlivierCruilles)
Et ce que j'en ai fait
Un lien vers un exemple pratique de la forge :
LMClassCommentaires 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 :
====================