IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

WinDev Discussion :

Arrêter instantanément un thread secondaire


Sujet :

WinDev

  1. #1
    Membre averti Avatar de LeonCosnyd
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 439
    Points : 368
    Points
    368
    Par défaut Arrêter instantanément un thread secondaire
    Bonjour,

    Je dois faire communiquer un terminal Windows connecté en WIFI à une base HFSQL C/S sur un serveur se trouvant sur le réseau local (pas d'internet).

    Étant donnée que le terminal est connecté en wifi (risque de coupure réseau, déconnexions intempestives,etc...) j'ai choisi de créer des fichiers locaux sur le terminal en HFSQL Classic. Depuis l'application j'utilise ces fichiers locaux (donc pas de soucis de lenteur ou de déconnexion).

    Pour alimenter ces fichiers locaux j'ai mis en place un système travaillant en arrière-plan (thread).
    Par exemple à l'ouverture d'une fiche CLIENT :
    1. L'application affiche les données du fichier local (Classic)
    2. Je lance une procédure locale ayant pour automatisme : Thread, Executée 1 fois immédiatement au moment de l'appel, Sans utilisation de HFSQL.
    Cette procédure ouvre une connexion au serveur HFSQL C/S, execute une requete SQL des informations du CLIENT, met à jour le fichier local.

    Voici un exemple de code, procédure syncDonneesClient :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
     
    SI HEtatServeur("192.168.1.99:4900") <> hDémarré ALORS RENVOYER(Faux)
     
    oConnexionHFSQL	est une Connexion
    oConnexionHFSQL	..Utilisateur 		= "MonIdentifiant"
    oConnexionHFSQL	..MotDePasse 		= "MonMotDePasse"
    oConnexionHFSQL	..Serveur			= "192.168.1.99:4900"
    oConnexionHFSQL	..BaseDeDonnées 	= "MaBaseDeDonnees"
    oConnexionHFSQL	..Provider  		= hAccèsHFClientServeur
    oConnexionHFSQL	..Accès   			= hOLectureEcriture
    oConnexionHFSQL	..OptionsCurseur 	= hCurseurClient
    oConnexionHFSQL	..Cryptage 			= hCryptageRC5_16
     
    SI HChangeConnexion("CLIENT_CS",oConnexionHFSQL) ALORS
    	SI HOuvreConnexion(oConnexionHFSQL) ALORS
    		HTransactionDébut(oConnexionHFSQL)
     
    		QUAND EXCEPTION DANS		
     
    			sdResultat est une Source de Données
    			SI HExécuteRequêteSQL(sdResultat,hRequêteInterruptible,"SELECT * FROM CLIENT_CS WHERE ..... ") ALORS
    				POUR TOUT sdResultat
    					HLitRecherche(CLIENT_LOCAL,IDCLIENT,sdResultat.IDCLIENT)
    					SI HTrouve(CLIENT_LOCAL) ALORS
    						HCopieEnreg(CLIENT_LOCAL,sdResultat,hCopieIdAuto)
    						HModifie(CLIENT_LOCAL)				
    					SINON
    						HCopieEnreg(CLIENT_LOCAL,sdResultat,hCopieIdAuto)	
    						HAjoute(CLIENT_LOCAL,hForceIdAuto)			
    					FIN
    				FIN
    			FIN
     
    			HTransactionFin(oConnexionHFSQL) 
    			HFermeConnexion(oConnexionHFSQL)
    		FAIRE
    			HTransactionAnnule(oConnexionHFSQL)
    			HFermeConnexion(oConnexionHFSQL)
    		FIN
    	SINON
    		RENVOYER(Faux)
    	FIN
    SINON 
    	RENVOYER(Faux)
    FIN
    Cela fonctionne plutôt bien.

    Je rencontre cependant un problème lorsque l'utilisateur veut quitter la fiche CLIENT si la synchronisation n'est pas terminée... J'ai un bouton "Quitter" qui ne fait que ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    FinAutomatismeProcédure(syncDonneesClient)
    ferme()
    La fenêtre passe alors en mode "je ne répond plus", couleur blanchâtre et ne se ferme pas. Jusqu'à (j'imagine) la fin de la synchronisation....
    Savez-vous si le FinAutomastismeProcédure() demande l'arrêt immédiat du traitement ou termine t-il la boucle en cours et s’arrête après ?

    En parcourant la documentation PcSoft j'ai vu la fonction ThreadArrete (en travaillant manuellement les threads) mais il est déconseillé pour différentes raisons.

    Avez-vous déjà été confronté au problème ? Et si oui quelles solutions avez-vous trouvez pour stopper le traitement le plus rapidement possible ?

    Merci d'avance.
    Google est ton ami !

  2. #2
    Expert éminent
    Avatar de frenchsting
    Homme Profil pro
    multitâches-multifonctions
    Inscrit en
    Juin 2003
    Messages
    5 187
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : multitâches-multifonctions
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 187
    Points : 9 171
    Points
    9 171
    Par défaut
    En mettant un multitache(-1) ?
    Commencez toujours appuyer sur la touche F1 et puis n'hésitez à passer par un moteur de recherche...
    Le forum est fait pour répondre aux questions : pas la peine de me les envoyer par MP. Merci.

    Sur internet, tout est vrai ! Honoré de Balzac
    Make it real not fantasy... Herman Rarebell

  3. #3
    Membre émérite
    Avatar de DelphiManiac
    Homme Profil pro
    Homme à tout faire
    Inscrit en
    Mars 2002
    Messages
    1 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Homme à tout faire
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 147
    Points : 2 533
    Points
    2 533
    Par défaut
    Il me semble que ton premier problème est que le code de ton thread est dans la fenêtre et que tu essayes de fermer celle ci sans savoir si le code est effectivement fini; d'autre part au vu de ton code, tu n'a pas moyen de l’arrêter proprement tant qu'il n'est pas effectivement fini. Si tu tentes de le stopper n'importe quand, ta connexion risque de rester ouverte et/ou la transaction pas finalisée.

    Conseil :
    - Place le code de ton thread dans une collection de procédures
    - Ne cherche pas a stopper le thread quand la fenêtre se ferme, la synchro sera faite et je ne pense pas que cela soit un problème, par contre tu risques du coup de déplacer le problème à la fermeture de l'application.
    - Le point au dessus implique un effet secondaire : le fait de ne pas stopper le thread fait que si l'utilisateur réouvre immédiatement la même fenêtre, le code du thread va être exécuté une deuxième fois sans que la première exécution soit finie. Il faut donc protéger le code de cette potentielle double exécution, un sémaphore devrait être la solution (à tester) https://doc.pcsoft.fr/fr-FR/?3077013.
    - Il faudrait aussi mettre en place un mécanisme empêchant la fermeture de l'application tant que le thread n'est pas fini.

    L'autre piste est stopper le thread proprement. Il faut pour cela mettre en place un indicateur dans la boucle de traitement du thread qui demande au thread d’arrêter le traitement.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    POUR TOUT sdResultat
    si demandeArret alors
        SORTIR
    fin
    et tu positionnes demandeArret à vrai dans le code principal. Par contre, ici aussi un problème potentiel, c'est que si la requête en début de thread prend beaucoup de temps, le thread ne pourra pas être interrompu avant la fin de la requête.

    -------
    Dans les 2 cas, il me semble qu'il serait préférable de gérer le thread manuellement :
    https://doc.pcsoft.fr/fr-FR/?3077004. Cela permet de lancer le thread, mais surtout de connaître son état fini ou pas.

    Le pseudo code serait donc
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    ProcédurePrincipale
    ThreadExécute("Thread1", threadNormal, ProcédureThread)
    
    ProcédurePrincipaleArret
    demandeArret = vrai
    tant que ThreadEtat("Thread1") = threadEncours
      threadPause(10)
    fin
    
    ProcédureThread
    tant que vrai
      si demandeArret alors
        sortir
      fin
    fin


    Si ce message vous a semblé utile, il est possible qu'il soit utile à d'autres personnes. Pensez au . Et n'oubliez pas le le moment venu !

    On n'a pas à choisir si l'on est pour ou contre la décroissance, elle est inéluctable, elle arrivera qu'on le veuille ou non.

Discussions similaires

  1. Arrêter / Stopper un Thread défini
    Par ouranos21 dans le forum Concurrence et multi-thread
    Réponses: 6
    Dernier message: 30/01/2008, 14h25
  2. arrêter/actualiser un thread
    Par hicham10 dans le forum GTK+ avec C & C++
    Réponses: 3
    Dernier message: 21/07/2007, 16h47
  3. Réponses: 14
    Dernier message: 04/06/2007, 22h43
  4. Réponses: 2
    Dernier message: 06/02/2007, 17h18
  5. Arrêter proprement le thread d'une JFrame
    Par fabrisss dans le forum Agents de placement/Fenêtres
    Réponses: 1
    Dernier message: 04/12/2006, 12h32

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo