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

VB 6 et antérieur Discussion :

Fonction Class_Terminate non appelée sur set nothing


Sujet :

VB 6 et antérieur

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Août 2006
    Messages
    88
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Savoie (Rhône Alpes)

    Informations forums :
    Inscription : Août 2006
    Messages : 88
    Points : 62
    Points
    62
    Par défaut Fonction Class_Terminate non appelée sur set nothing
    Voila je vais essayer de vous exposer mon problème le plus clairement possible mais j'avoue que ça va peut être facile, moi même je comprend pas ce que je veux expliquer

    Tout simplement, quand je veux terminer une classe je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    set activeClass = nothing 'ou activeClass est mon objet
    Ce qui a normalement pour effet d'appeler la procédure "Class_Terminate()" de ma classe. Et bien dans un cas précis l'appel à la procédure "Class_Terminate" se fait une fois sur deux quand je fais mon set activeClass = nothing. Une fois ça marche l'appel se fait, la fois d'après dans le même conetxte l'appel ne se fait pas (en mode pas à pas l'execution passe tout droit et ne rentre pas dans la procédure Class_Terminate....). Pourtant l'object devient bien nothing... Pas de message d'erreur....

    La seule particularité que je puisse voir dans cette classe est l'utilisation d'un timer pour lancer des traitements toutes les secondes.... Alors est ce que la procédure "Class_Terminate" ne peut être appelée pendant un tick du timer... Je ne sais pas du tout.

    Voila c'était juste pour savoir si quelqu'un avait déjà eu ce cas de figure ou avait une petite idée. S'il faut du code, des explications supplémentaires ou quoi que ce soit d'autre dites le moi (sacahtn que de toute façon je peux me dépanner en faisant l'appel moi même à "Class_Terminate")

    Merci pour votre aide, a bientôt

  2. #2
    Membre expérimenté
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2006
    Messages
    1 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Argentine

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 173
    Points : 1 418
    Points
    1 418
    Par défaut
    ahhh ça me rappelle quelque chose .. tu peux coller la fonction dans laquelle tu fais ton set activeclass = nothing ?

    D'autre part, activeclass est-elle une form ?

  3. #3
    Membre expérimenté
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2006
    Messages
    1 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Argentine

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 173
    Points : 1 418
    Points
    1 418
    Par défaut
    J'ai 2 réponses potentielles :

    1/ Activeclass est déclarée en public dans une classe Globale multi use, et tu n'as pas pensé à liquider les autres pointeurs (créés à chaque fois que tu instancies la class une autre fois)

    2/ Activeclass est une classe référencée par une autre classe, qui elle même est référencée par Activeclass. Ceci s'appelle une référence circulaire, non gérée par vb6 en l'état mais implémentable en passant par une weak-reference [...] Un des effets non désirables de ce type d'implémentation est ça : fuite mémoire.

    Voilà, j'espère que ça pourra t'aider ...
    A+
    Seb

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Août 2006
    Messages
    88
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Savoie (Rhône Alpes)

    Informations forums :
    Inscription : Août 2006
    Messages : 88
    Points : 62
    Points
    62
    Par défaut
    Bonjour Seb,

    La fonction ne te servira pas à grand chose tu vas voir :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        Private Sub objActiveClassTerminate()
            objActiveClass.Class_Terminate 'ce que j'ai rajouté pour forcer.... marche faut de mieux
            Set objActiveClass = Nothing
        End Sub
    Ca me sert juste à faire un nom moins long pour appeler l'instruction (question subsidiaire, ce genre de petit raccourci est-il vraiment consommateur en ressource; i-e l'appel à une fonction qui execute une instruction plutôt que d'appeler l'instruction directement)

    Pour revenir à nos moutons je penche vers la solution 2 : Activeclass est un module de classe standard. J'ai dans mon projet une fenêtre principale avec un certain nombre de frame et un treeview principal (treeMain).
    Un clic sur le treeview détruit la classe active (activeClass) et instancie une classe associée.
    Le principe est que chaque classe, lors de son appel, affiche et gère les contrôles du frame correspondant.

    Voici l'appel des classes (j'ai épuré du superflue bien entendu , en fait j'ai refais mais le principe est identique )
    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
    'TRAITEMENT GENERALE D'AFFICHAGE DES INFOS PAR CLASSE
        Private Function showInfos(ByVal Node As String) As Boolean
    'node = texte du noeud cliqué 
        On Error GoTo erreur
     
            'Termine la classe active
            objActiveClassTerminate 'ici appel de la fonction qui détruit la classe active, centre du problème
            'Taitement en fonction du noeud
            select case Node = "Hosts" 
                    Case "Process"
                        Set objActiveClass = New C_Process 'instanciation des classes vers objActiveClass
                    Case "Sys"
                        'Set objActiveClass = New C_System
                    Case "Registry"
                        Set objActiveClass = New C_Registry
                    Case "Services"
                        Set objActiveClass = New C_Services
                    Case "Perfs"
                        Set objActiveClass = New C_Perfs
                End Select
            'Si le chargement est réussi on démarre la classe
            If IsObject(objActiveClass) Then
                    objActiveClass.startClass Me, typeTrait, host 'ici on initialise la classe avec les paramètres, c'est par là je te rejoins sur ton point 2 car effectivement je passe la form en paramètre et j'en garde une trace dans la classe (cf ci dessous)
            End If
            showInfos = True
            Exit Function
    erreur:
            showInfos = False
        End Function
    Voici à quoi ressemble une classe (pareil j'ai épuré viol)
    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
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    Option Explicit
     
    'DECLARATION DES VARIABLES DE CLASSE
    '###############################################################################################################
    'Form principale
    Private parentForm As frmMain
    Private wmiConnexion As Object
    'Variable de traitements
    Private typeTrait As String
    Private host As String
    Private item As Object
    Private reqResult As Object
    'Controles
    Private WithEvents timer As timer
    Private WithEvents lstMain As ListView
    '###############################################################################################################
     
    'GESTION DE LA CLASSE
    '###############################################################################################################
        Public Function startClass(ByVal aform As Object, ByVal vartypeTrait As String, ByVal varHost As String)
            'Déclaration de la form parente et affichage de la tab associée
            Set parentForm = aform
            parentForm.tabMain.Tab = getTabIndex(parentForm.tabMain, "Perfs")
            ' Récupération des contrôles et de leur events
            Set timer = parentForm.perfTimer
            Set lstMain = parentForm.perfLstMain
            'Traitement des variables
            typeTrait = vartypeTrait
            host = varHost
            'Définition de la connexion
            Set wmiConnexion = parentForm.colConnexion(host)(2)     
     
            Dim classTmp As New SC_Perfs_Object
            'ici j'initialise une sous classe que j'ajoute à la collection des compteurs de performances, je me demande si j'ai pas un pb par là ?
            classTmp.startClass Me, "Proc|ProcTime", "Processeur : Charge de l'UC" 'cette classe est différente, elle ne comporte aucune référence
            'J'ajoute la classe dans le compteur (collection de la form principale)
            parentForm.colConnexion(host)(2).Add classTmp
            'et je la détruis bien cette classe après l'avoir ajouté
            Set classTmp = Nothing
            'Maj de l'interface
            timer.Enabled = True
        End Function
     
        Public Sub Class_Terminate()
            'Maj de l'interface
            timer.Enabled = False
            'vidage de la liste principale
            lstMain.ListItems.Clear
            'Libération mémoire (ici je détruis les références)
            Set parentForm = Nothing
            Set wmiConnexion = Nothing
            Set timer = Nothing
            Set lstMain = Nothing
            Set colCompteur = Nothing
        End Sub
    '###############################################################################################################
    Je pense clairement à:

    1) Un problème avec le timer et surtout son pointeur dans la classe (style si je fais timer = nothing si il est en train de ticker par ex, bien que ce ne soit pas normalement possible vu que je fais enabled = false avant....)

    2)Ou un problème avec la sous classe que j'instancie dans la fonction start_class et que je référence dans une des collection de la classe appelante. Ce qui rejoint l'histoire des références circulaires MAIS je pensais qu'en détruisant la classe temporaire après ajout dans la collection de la classe appelante il n'y aurais pas de soucis.

    J'éspère que tu vas réussir à y comprendre quelque chose . En tout cas merci de te pencher sur mon soucis. Et si tu veux avoir un aperçu du projet dans son ampleur tu peux aller voir ici :http://www.developpez.net/forums/sho...d.php?t=535238
    Sachant que la version du zip est plus ancienne et qu'elle n'inclue pas la classe incriminée. Mais par contre le principe de fonctionnement n'a pas changé.


    @+ zesamoth

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Août 2006
    Messages
    88
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Savoie (Rhône Alpes)

    Informations forums :
    Inscription : Août 2006
    Messages : 88
    Points : 62
    Points
    62
    Par défaut
    Quand tu dis une classe référencée par une autre classe etc,etc... Est ce que un truc dans ce genre poserait problème ?
    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
    46
    47
    48
     
    'Première classe mettons formMain
    '#########################
    'Variables de classe
    Private classAppelee as classToto
    Public collection as collection
     
    Private sub Form_Load()
        'instanciation de la collection
        set collection = new collection
        'Instanciation et démarrage de la classe appelée
        set classAppelee = new classToto
        classAppelee.startClass me 
        'et destruction
        set classAppelee = nothing
    end sub
    '#########################
     
    '#deuxième classe mettons classToto
    '########################
    'Variables de classe
    private classAppelante as formMain
    Private classAppelee as classTiti
     
    Public function startClass (byval aClassAppelante as formMain)
        set classAppelante = aClassAppelante
        'Instanciation et démarrage de la classe appelée
        set classAppelee = new classTiti
        classAppelee.startClass me 
        'ajout de la classe appelée dans la collection de la classe appelante et destruction
        classAppelante.collection.add classAppelee
        set classAppelee = nothing
    end function
    '########################
     
    'troisième classe mettons classTiti
    '########################
    'Variables de classe
    Private classAppelante as classToto
     
    Publicfunction startClass (byval aClassAppelante as classToto)
        set classAppelante = aClassAppelante
    end function
     
    Public Sub Class_Terminate()
        set classAppelante = nothing
    end sub
    '########################
    Pour moi ce code ne pose pas de problèmes dans le sens ou je n'ai que des passages par ByVal et que les objets sont détruits dans un ordre logique. Me tromperais-je ? Parce que, en très résumé, c'est ce que je fais dans mon projet.

    @+

    EDIT : Je viens de faire des tests, j'ai effectivement un problème de référence circulaire... Merci pour ton aide de grand secour !

  6. #6
    Membre expérimenté
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2006
    Messages
    1 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Argentine

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 173
    Points : 1 418
    Points
    1 418
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    dim obj1 as class1
    dim obj2 as class2
     
    set obj1 = new class1
    set obj2 = new class2
     
    set obj1.truc = obj2
    set obj2.machin = obj1
    empêche la destruction des objects obj1 et obj2, quoi que tu fasses.

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Août 2006
    Messages
    88
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Savoie (Rhône Alpes)

    Informations forums :
    Inscription : Août 2006
    Messages : 88
    Points : 62
    Points
    62
    Par défaut
    Ouais c'est un peu ce que je faisais sur 3 classes. Par contre je comprend pas trop pourquoi ça marchait une fois sur 2... Ca doit être autre part dans le projet

    Citation Envoyé par Vld44 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    dim obj1 as class1
    dim obj2 as class2
     
    set obj1 = new class1
    set obj2 = new class2
     
    set obj1.truc = obj2
    set obj2.machin = obj1
    empêche la destruction des objects obj1 et obj2, quoi que tu fasses.
    et induit j'imagine un problème de mémoire dans le sens :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    obj1.truc.machin.truc.machin.truc.machin etc....

  8. #8
    Membre expérimenté
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2006
    Messages
    1 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Argentine

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 173
    Points : 1 418
    Points
    1 418
    Par défaut
    je ne sais pas trop les rouages internes, mais je crois qu'il s'arrête assez vite après un constat de type deadlock.

    Du coup tu restes avec 2 objets sur les bras ....

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Août 2006
    Messages
    88
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Savoie (Rhône Alpes)

    Informations forums :
    Inscription : Août 2006
    Messages : 88
    Points : 62
    Points
    62
    Par défaut
    Pour info j'ai supprimé mes références circulaires et ça marche du feu de dieu. Merci pour ton aide

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Fonction UDF non reconnu sur un poste client
    Par obione dans le forum Firebird
    Réponses: 12
    Dernier message: 17/06/2010, 16h07
  2. [Compiler] Fonction mapleinit non utilisable sur fichier compilé
    Par Ocarlo dans le forum MATLAB
    Réponses: 1
    Dernier message: 25/05/2010, 10h13
  3. Fonction js non appelée sous firefox.
    Par DevServlet dans le forum JSF
    Réponses: 13
    Dernier message: 14/09/2009, 15h12
  4. valueUnbound non appelé sur Was 6 alors que
    Par paquerette dans le forum Servlets/JSP
    Réponses: 3
    Dernier message: 18/06/2008, 15h49
  5. Menus : fonction "tri" non disponible sur un autre PC
    Par niavlys77 dans le forum Access
    Réponses: 1
    Dernier message: 02/05/2006, 19h39

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