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

VBA Access Discussion :

Création d'un Thread


Sujet :

VBA Access

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre émérite Avatar de Ric500
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    981
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aude (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 981
    Par défaut Création d'un Thread
    Bonjour à tous!

    J'essaie actuellement d'encapsuler un traitement (calcul de balance comptable) assez long dans mon appli. La création d'un thread me paraît indiquée dans ce cas et j'ai donc mis en place les déclarations et la fonction AddrOf(fonction) dans mon code.
    A la compil, pas de problème. L'appel de la fonction se fait correctement, mais il me semble avoir un problème avec la fonction "GetCurrentVbaProject(hProject)" (appelée depuis la fonction AddrOf): à sa sortie la variable hProject a toujours la valeur 0 et le traitement ne se poursuit pas, bien sûr.
    J'avoue que j'utilise ce code "copié-collé" depuis la FAQ sans le comprendre entièrement, mais pour ce que j'en sais, il pourrait résoudre mon problème.
    Je soupçonne que le problème se trouve dans l'appel de la fonction reproduit ci-après:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Sub CalculBalance411Solid()
              hThread = CreateThread(0&, 0&, AddrOf("CalculBalance411Solid"), 0&, 0&, hThreadID)
              CloseHandle hThread
              Dim e As Long
              e = TerminateThread(hThread, 0)
    End Sub
    J'ai passé ces paramètres sans en comprendre le sens .
    En l'attente de vos conseils éclairés, merci d'avance.

  2. #2
    Membre Expert
    Homme Profil pro
    Développeur VBA Access
    Inscrit en
    Avril 2006
    Messages
    1 109
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur VBA Access

    Informations forums :
    Inscription : Avril 2006
    Messages : 1 109
    Par défaut
    Bonjour,
    si je comprends ton code, tu crées un thread pour ta procédure de création de thread ?? Il est peut-être heureux que ton code n'a pas fonctionné.

    La fonction AddrOf n'est-elle pas censée être l'équivalent Access97 de l'instruction VBA AddressOf des versions suivantes renvoyant l'adresse d'une fonction (pour les procédures je ne suis pas sûr) publique.

  3. #3
    Membre émérite Avatar de Ric500
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    981
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aude (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 981
    Par défaut
    En fait je crée un thread qui appelle un "sub" qui lui même calcule enregistrement par enregistrement, le solde (débit-crédit) d'une table 401-fournisseurs.
    J'ai effectivement trouvé le post suivant:
    http://www.developpez.net/forums/d56...sation-thread/
    et modifié mon code en conséquence sans plus de succès.
    (viré les références à vba332.dll) et remplacé l'appel de AdrOf par AddressOf).
    Pour répondre à ta question: j'avais une procédure appelée "CalculBalance411Solid" dont j'ai coupé-collé le code dans "CalculBalance411SolidThread": j'appelle cette dernière comme suit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Sub CalculBalance411Solid()
              hThread = CreateThread(ByVal 0&, ByVal 0&, AddressOf CalculBalance411Solid_Thread, ByVal 0&, ByVal 0&, hThreadID)
              CloseHandle hThread
              Dim e As Long
              e = TerminateThread(hThread, 0)
    End Sub
    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
    Sub CalculBalance411Solid_Thread()
              Dim mabd As Database, MonRec As Recordset, StrSQL As String, Balance As Currency, LaDate, Crit As String, WithBall As String, rep
     
     
              Set mabd = CurrentDb()
              StrSQL = "SELECT CCCpt, CCDeb, CCCre, CCBalSolid, CCDat FROM CPTE_CAISSE_Cli ORDER BY CCDat;"
              Set MonRec = mabd.OpenRecordset(StrSQL)
              DoCmd.Echo True, "Mise à jour de la balance compte clients, veuillez patienter..."
              DoCmd.OpenForm "PgBar"
              Forms!PgBar!PTxt = "Mise à jour de la balance globale..."
              DoEvents
     
              Do While MonRec.EOF = False
                        MonRec.Edit
                        Forms!PgBar!PgBar = MonRec.PercentPosition
                        Forms!PgBar!Pct = MonRec.PercentPosition / 100
                        Forms!PgBar.Repaint
                        DoEvents
                        LaDate = MonRec!CCDat
     
                        Balance = Nz(DSum("CCCre", "CPTE_CAISSE_Cli", "CCDat<=#" & Format(LaDate, "mm/dd/yyyy hh:nn:ss") & "#"), 0) - Nz(DSum("CCDeb", "CPTE_CAISSE_Cli", "CCDat<=#" & Format(LaDate, "mm/dd/yyyy hh:nn:ss") & "#"), 0)
     
                        MonRec!CCBalSolid = Balance
                        MonRec.Update
                        'DoEvents
                        MonRec.MoveNext
              Loop
              MonRec.Close
              DoCmd.Close acForm, "PgBar"
              DoCmd.Echo True, ""
    End Sub
    Voilà où j'en suis de mes réflexions pour l'instant et merci Ilank de ton attention (pour l'appel récursif c'était une erreur de frappe...)

  4. #4
    Membre chevronné Avatar de Tonioyo
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2008
    Messages
    343
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juin 2008
    Messages : 343
    Par défaut
    Bonsoir,

    Si je me rappelle de ce que j'avais fait fait sur les thread, il y a fort longtemps, une fois le thread créé il est nécessaire de le lancer.

    Attention aussi à ce que le code appellant reste chargé en mémoire durant l'éxection du thread sinon on obtiens un thread orphelin et là ... bonjour l'état de la mémoire.

    Il faut savoir que les deux principaux systèmes d'exploitations ne possèdent pas de "garbage collector" pour nettoyer ces threads orphelins.

    Il faut aussi s'assurer à la désallocation du code parent de la bonne désallocation du thread en mémoire. Ce qui est très probablement fait avec

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    e = TerminateThread(hThread, 0)

    Un autre aspect très important en ce qui concerne les threads est le mécanisme de ressources. Un thread peu consommer / produire une / plusieurs ressources. La difficulté de la programmation par thread est de ne pas se trouver en conditions d'interblocage ce qui paralyserai l'ordinateur (et non pas simplement access) surtout à cause (de mémoire) de l'attente active sur la ressource.

    Il faut aussi penser au mécanisme des interruptions pour pas que le thread s'arrête à l'instant t ou il ne devrait jamais s'arrêter. C'est surtout critique pour les systèmes embarqués.

    Pour adressOf ce n'est qu'une instruction qui permet d'avoir l'adresse en mémoire du début d'un objet / d'une fonction.

    Attention aussi au rôle des CallBack qui sont un mécanisme important des threads. Toujours de mémoire, ces méthodes sont les méthodes principale / de démarrage du thread. Elles sont analogues au main en C / C++ / Java et elle doivent très probablement respecter une signature particulière.

    J'espère avoir été utile et avoir permis diriger la reflexion vers la solution pour votre problème.

    Cordialement,

  5. #5
    Membre Expert
    Homme Profil pro
    Développeur VBA Access
    Inscrit en
    Avril 2006
    Messages
    1 109
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur VBA Access

    Informations forums :
    Inscription : Avril 2006
    Messages : 1 109
    Par défaut
    Ok, tu fais trop régulièrement appel au DoEvents dans ton code ce qui ralentit l'exécution du code.
    Pour faire simple, ton formulaire n'a en fait besoin d'être rafraichi qu'après chaque 1% de tâche accomplie. Soit un test du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    If CurPercent >= OldPercent + 1 Then
     OldPercent=CurPercent
     form.Repaint
     DoEvents
    End If
    limite le nombre de DoEvents à 100.
    Je ne crois pas qu'il soit suffisant de créer un thread pour qu'il s'exécute pour autant, à voir ?

    Sinon, il y a ici une première ébauche de simulation de multithreads sans threads.

  6. #6
    Membre chevronné Avatar de Tonioyo
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2008
    Messages
    343
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juin 2008
    Messages : 343
    Par défaut
    J'ai trouvé en première partie d'un article la définition d'un thread
    http://alwin.developpez.com/tutorial/JavaThread/

    Un thread doit être démarrer pour qu'il puisse fonctionner. A la création d'un thread, des arguments obligatoires et le plus important est celui de la routine.

    La routine d'éxecution est une méthode qui serra executée tant que le thread serra en vie et actif. C'est à dire qu'il n'y a pas besoin d'écrire de boucle à l'intérieur du code de la routine.
    Dans l'exemple du premier article cité il s'agit des CallBacks.
    Donc par exemple, une routine qui aurait ce code :

    Passe toute sa vie à incrémenter la variable i qui soit dit en passant doit être accessible donc déclarée au minimum static.

    Pour la programmation de threads, la difficulté est de gérer les problèmes d'accès concurentiels aux ressources (par exemple la variable i). Ce qui dans le cas présent concerne tous les objets manipulés à l'intérieur de la routine.

    Les objets manipulés sont des objets Access et la routine va s'éxecuter de manière totalement indépendante du contexte d'execution. Donc l'accès à des objets d'Access risquent fortement d'être compromis.

    Le paramètre pour la routine est un pointeur sur fonction (j'ai donc de sérieux doutes concernant une Sub qui est une procedure).

    D'où la méthode AddrOf de l'article, à éventuellement remplacer par AddressOf dans les versions d'Access plus récentes.

    La méthode AddrOf calcule l'adresse mémoire de la première instruction à éxecuter d'une méthode passée en paramètre.

    La mise en place d'un traitement lourd dans un thread n'est pas chose facile.
    L'utilisation du thread ici serrai de prendre en charge uniquement le calcul mathématique des données à traiter.

    Cordialement,

  7. #7
    Membre émérite Avatar de Ric500
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    981
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aude (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 981
    Par défaut
    Merci Ilank et Tonioyo de vos réponses,

    Je vais essayer d'utiliser vos réponses dans mon appli. Même si le thread s'avère difficile à mettre en place dans ce contexte, j'ai réussi à diminuer le temps de traitement du calcul des balances de moitié .

    Cela dit je m'enferre peut-être sur cette voie ??? Il existe peut-être une méthode simple pour effectuer ce genre de calculs.

    En gros une colonne débit, une colonne crédit et une colonne balance:
    basiquement, balance= somme(débit - crédit).

    Ce qui plombe ce calcul c'est l'utilisation de fonctions de domaine au lieu de SQL.

    Merci encore de votre intéret.

Discussions similaires

  1. passer des parametres a la création d'un thread
    Par LesLemmings dans le forum Visual C++
    Réponses: 1
    Dernier message: 08/03/2007, 12h35
  2. création d'un thread a la reception d'un message sur une socket
    Par jesus144 dans le forum Programmation et administration système
    Réponses: 1
    Dernier message: 05/03/2007, 17h27
  3. [WD11] Création d'un thread
    Par arnaud_verlaine dans le forum WinDev
    Réponses: 2
    Dernier message: 17/02/2007, 16h14
  4. [VB.NET]Création d'un thread
    Par Oufti dans le forum Windows Forms
    Réponses: 1
    Dernier message: 21/11/2006, 10h01
  5. création de plusieurs threads dans WinMain
    Par ChidoriRasengan dans le forum DirectX
    Réponses: 1
    Dernier message: 15/06/2005, 21h36

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