2009-12-21 4 views
0

J'ai une DLL VB6 intégrée dans certaines pages ASP. La DLL rencontre une base de données Codebase, un moteur de base de données obsolète et obsolète (un dialecte/variation sur dBase) dont pratiquement personne n'a entendu parler. Il faut près d'une seconde à Codebase pour initialiser une nouvelle connexion, ce qui est inacceptable et j'ai donc créé un pool de connexions, géré par une classe VB. La seule instance de cette classe est créée au début d'un module VB, i.e. .:Réinitialisation inattendue des variables déclarées dans le module DLL VB6

Private m_codebaseManager As New CodebaseManager 

Mon problème est que périodiquement la méthode d'initialisation de classe est appelée à nouveau démolition complètement ma classe de mise en commun et je n'ai aucune idée pourquoi. Terminate ne se déclenche pas et il n'y a aucun signe de crash, alors pourquoi diable est-il appelé? Ma compréhension est que les données dans les modules non-classe persistent pour la durée de vie de la DLL. Est-ce correct et si non, dans quelles circonstances un module redémarre-t-il?

Répondre

5

Je recommande de supprimer le "Nouveau" de la déclaration de variable. Déclarer une variable "comme nouvelle" la fait vérifier chaque fois qu'elle est référencée, et si elle est définie sur Nothing, une nouvelle instance de votre CodebaseManager sera créée.

Une meilleure solution serait de déclarer votre variable comme ceci:

Private m_codebaseManager As CodebaseManager 

puis définir explicitement à une nouvelle instance lorsque votre application démarre:

Set m_codebaseManager = New CodebaseManager 

Cela signifie que vous pouvez être sûr vous ne créerez pas de nouvelles instances involontaires de CodebaseManager. Vous aurez probablement toujours un bogue mais au moins ce sera une erreur "Objet ou avec une variable de bloc non définie" que vous devriez pouvoir facilement corriger.

0

Mais il s'agit d'une DLL et non d'un exe ActiveX, donc il n'y a pas de fonction Main() et nulle part la ligne 'Set m_codebaseManager = Nouveau CodebaseManager' sauf dans la portée globale.

+0

Vous pouvez créer une fonction Register() dans le module et l'appeler depuis Class_Initialize des classes que vous exposez dans votre DLL. Dans la fonction Register(), utilisez quelque chose comme Si non m_codebaseManager est rien alors Set m_codebaseManager = New CodebaseManager Vous pouvez également coller un point d'arrêt sur Class_Initialize dans votre classe CodebaseManager et vous devriez voir exactement où les instances supplémentaires sont créés . –

1

Ma compréhension est que les données dans les modules non-classe pour la durée de vie persiste de la DLL. Est-ce correct et si non, dans quelles circonstances un module redémarre-t-il?

Trier par. L'état global (module public/private vars) est spécifique à l'appartement et est stocké dans des emplacements TLS. VB6 ne prend en charge que le thread d'appartement, de sorte que chaque thread obtient une copie "fraîche" de l'état global. Étant donné que l'environnement ASP est multithread, chaque thread obtient un "pool" de connexion DB distinct.

Si vous avez besoin d'un état global réel, vous devez utiliser l'objet Application pour le stocker. Si vous y placez des objets threads d'appartement (comme ceux de VB6), ceux-ci peuvent sérialiser votre environnement ASP multi-thread et dégrader les performances. Utilisez des objets ADO ou des objets Dictionnaire ou tout ce dont vous avez la certitude qu'il est libre. Btw, vous pouvez laisser COM + faire le regroupement objet/connexion pour vous. Si le fournisseur OLEDB est meilleur, il peut aussi faire du pooling de connexions en interne (SQLOLEDB pour MSSQL en est un exemple).

Questions connexes