Est-il nécessaire de définir les objets à rien à l'intérieur des fonctions VBA
-
21-08-2019 - |
Question
Je lis toujours qu'il est recommandé de mettre des objets à rien, une fois que je suis fait avec eux. Mais je les utilise normalement en fonctions à l'intérieur des formes.
est-ce pas la référence perdue et la mémoire libérée lorsque la portée de la fonction reste, quel que soit la mise en objets à rien?
i.e.. est-il vraiment nécessaire de faire:
Set db = Nothing
Set record_set = Nothing
La solution
VB utilise un soi-disant "comptage de référence" garbage collector.
En fait, le moment une variable est hors de portée, le compteur de référence sur l'objet référencé est décrémenté. Lorsque vous attribuez la référence d'objet à une autre variable, le compteur de référence est incrémenté.
Lorsque le compteur atteint zéro, l'objet est prêt pour la collecte des ordures. Les ressources de l'objet seront libérés dès que cela se produit. Une fonction variable locale sera très probablement référence à un objet dont seront libérés le nombre de référence ne va jamais supérieur à 1, donc objet de ressources lorsque la fonction se termine.
Définition d'une variable est le moyen Nothing
de diminuer le comptoir de référence explicitement.
Par exemple, vous lisez dans un fichier, et définissez la variable d'objet fichier à droite après l'ReadAll()
appel <=>. Le descripteur de fichier sera disponible immédiatement, vous pouvez prendre votre processus de temps son contenu.
Si vous ne définissez pas <=>, le descripteur de fichier peut être ouvert plus longtemps que nécessaire.
Si vous n'êtes pas dans une « ressource précieuse doit débloquer » genre de situation, laissant simplement les variables hors de portée est correct.
Autres conseils
Collecte des ordures ménagères est rarement parfaite. Même dans .NET il y a des moments où vous êtes fortement encouragés à inciter le système à faire tôt la collecte des ordures.
Pour cette raison, je explicitement à la fois Fermer et mis à Rien recordsets quand je suis fait avec eux.
La dernière ligne de la rubrique d'aide pour « Recordset.Close » dans l'aide de Microsoft DAO et l'accès Référence Developer est le suivant:
"Une alternative à la méthode Close est pour définir la valeur d'une variable d'objet Nothing (Set dbsTemp = Nothing). "
http://msdn.microsoft.com/en-us/library/ bb243098.aspx
Dans cet esprit, cet article de la Base de connaissances Microsoft intitulé « Comment prévenir la base de données ballonnement après avoir utilisé Data Access Objects (DAO) », vous dit que vous devez fermer explicitement si vous ne voulez pas que vos bases de données de ballonnement. Vous remarquerez que l'article est un peu vague sur les détails; la section « Cause » ne sait pas, presque au point d'être du charabia.
http://support.microsoft.com/kb/289562
Symptômes: Une base de données Microsoft Access a commencé à enfler (ou se développer rapidement taille) après avoir implémenté accès aux données Objets (DAO) pour ouvrir un jeu d'enregistrements.
Cause: Si vous ne relâchez pas La mémoire de chaque fois recordset que vous une boucle à travers le code du jeu d'enregistrements, DAO peut recompiler, en utilisant plus de mémoire et augmenter la taille de la base de données.
Plus d'informations: Lorsque vous créez un D'enregistrements (ou un QueryDef) objet code, fermer explicitement l'objet lorsque vous avez terminé. Microsoft Access se ferme automatiquement et d'enregistrements objets QueryDef sous la plupart des conditions. Toutefois, si vous fermer explicitement l'objet dans votre code, vous pouvez éviter de temps en temps cas où l'objet reste ouvert.
Enfin, permettez-moi d'ajouter que je travaille avec des bases de données d'accès depuis 15 ans, et je laisse presque toujours mes variables déclarées localement recordset hors de portée sans utiliser explicitement la méthode Close. Je ne l'ai pas fait de tests sur elle, mais il ne semble pas à la matière.
Les références sont censés être nettoyés lorsque la variable est hors de portée. On peut supposer que cela a amélioré avec les versions ultérieures du logiciel, mais il était à un moment pas fiable. Je crois qu'il reste une bonne pratique de définir explicitement les variables à « rien ».
Lorsque vous utilisez ASP classique (de script côté serveur), il est l'importation de mettre tous les objets à rien quand vous êtes à travers avec eux, parce qu'ils ne vont pas hors de portée jusqu'à ce que le serveur [virtuel] est arrêté.
Pour cette raison, tous les exemples de scripts MS VB ont toujours montré des objets étant fermés et mis à rien. Alors que les extraits de script peuvent être utilisés dans des environnements comme ASP classique où les objets ne sont pas hors de portée.
Il y a, rarement, d'autres situations où vous souhaitez coder processus de longue durée où les objets ne vont pas hors de portée, et vous vous retrouvez à court de mémoire physique si vous ne relâchez pas explicitement des objets.
Si vous vous trouvez codage ASP classique, ou l'exécution de processus dans le contexte global pour une autre raison, alors oui, vous devez libérer explicitement des objets.
Je mets habituellement toujours ceci à la fin de mes procédures, ou appeler un sous avec « CloseRecordSet » dans si j'utilise les niveau des modules:
Private Sub Rawr()
On Error GoTo ErrorHandler
'Procedural Code Here.
ExitPoint:
'Closes and Destroys RecordSet Objects.
If Not Recset Is Nothing Then
If Recset.State = 1 Then
Recset.Close
Conn.Close
End If
Set Recset = Nothing
Set Conn = Nothing
End If
Exit Sub
ErrorHandler:
'Error Handling / Reporting Here.
Resume ExitPoint
End Sub
De cette façon, mais la procédure se termine, (soit normalement ou en raison d'une erreur) les objets sont nettoyés et des ressources sont disponibles.
Faire de cette façon est tout à fait sûr en ce qu'il vous suffit de le gifler et il ne le fera que ce qui est nécessaire en ce qui concerne la fermeture ou la destruction de l'objet recordset / connexion, Incase il a déjà été fermé (en raison d'un erreur d'exécution ou la fermeture juste tôt ya devrait, ce juste veille).
Il est vraiment pas beaucoup de tracas et son toujours préférable de nettoyer vos objets lorsque vous avez terminé avec eux pour libérer des ressources immédiatement, peu importe ce qui se passe dans le programme.
Essayer cette
If Not IsEmpty(vMyVariant) Then
Erase vMyVariant
vMyVariant = Empty
End If