Je gère un service Windows multithread qui doit appeler une DLL VB6. Il n'y a aucune documentation sur cette DLL VB6 et ce système héritée prend en charge un processus métier très critique. P>
À la première fois (1ère filetage), cette DLL fonctionne bien. Comme d'autres threads ont besoin d'un accès, il commence à fournir de faux résultats. P>
J'ai lu un des gars disant: p>
"Faites attention à une chose si vous utilisez VB6. Votre filetage Le modèle va devoir changer pour supporter des appartements si vous êtes exécuter un service multithreadé. VB ne prend en charge que plusieurs appartements à une seule-fileté, mais .Net court complètement fileté libre normalement. Le fil qui appelle dans la DLL VB6 doit être Compatible avec la DLL. " P> blockQuote>
Un autre gars de l'équipe m'a donné l'idée de mettre ce DDL dans un domaine d'application séparé. Mais je ne suis pas sûr. P>
Comment pouvons-nous travailler avec VB6 DLL appelé à partir d'une application de service Windows C # multithreaded C #? P>
4 Réponses :
Cet article sur Multhreading Visual Basic 6 DLL's A> fournit une idée. Il dit: Pour faire un projet de DLL ActiveX
multithreaded, sélectionnez le souhaité souhaité
Options de filetage sur l'onglet Général
de la boîte de dialogue Propriétés du projet. P>
blockQuote> Cet article dit qu'il y a trois modèles possibles à choisir parmi: p> Je suppose que la valeur par défaut est
un thread d'exécution code>, et celui des deux autres Les options doivent être sélectionnées. P> P>
Vous voudrez peut-être jeter un coup d'œil à ceci: Linky p>
Et voici un extrait qui a attiré mon attention: p>
Les objets COM VB6 sont des objets STA, cela signifie qu'ils doivent s'exécuter sur un fil de STA. Vous avez créé deux instances de l'objet à partir de deux threads MTA, mais l'objet lui-même fonctionnera sur une seule (COM (OLE) créée) STA Le fil et l'accès des deux threads MTA seront fermés et synchronisés. Donc ce que vous devriez faire est d'initialiser les threads comme STA afin que chaque objet fonctionne sur son propre fil de STA sans le marshaling et vous ira bien. P>
Quoi qu'il en soit, les objets COM Style VB sont toujours STA. Maintenant, afin d'empêcher le maréchalage de l'appartement et la commutation de fil, vous devez créer cas dans les appartements initialisés de STA. Notez également que lorsque vous définissez l'attribut [mTathread] sur MAIN, vous initialisez efficacement le fil principal en tant que MTA, lorsque vous créez. Les instances d'objets STA de MTA threads com créeront un thread séparé (non géré) et l'initialisera comme STA (ceci s'appelle le STA par défaut), tous les appels vers les objets STA à partir de threads MTA seront mis au rebut (et incurvoir des interrupteurs de thread), dans certains cas, des appels IDISPatch échouera à cause des échecs marshaling IP. Ainsi, les conseils utilisent des objets STA (et donc VB6) à partir d'appartements compatibles uniquement. P> blockQuote>
Lorsque les threads entrent, enregistrez-vous des objets et les réutilisez-vous plus tard sur de nouveaux threads? Si vous le pouvez, créez les objets frais pour chaque fil. Nous avons une situation comme celle-ci avec une DLL de la couche de données que nous utilisons. Si vous créez une connexion sur un thread, elle ne peut pas être utilisée d'une autre. Si vous créez une nouvelle connexion sur chaque thread, cela fonctionne bien.
Si elle est lente de créer vos objets, regardez la classe ThreadPool et l'attribut threadstatique. Threadpools recyclez le même ensemble de fils sur et sur le travail pour faire du travail et vous permet de créer un objet qui existe uniquement pour un fil uniquement. EG P>
void DoWork() { if (myObject == null) { // slow intialisation process myObject = New ... } // now do the work against myObject myObject.DoGreatStuff(); }
vous dites p>
Je gère une fenêtre multithreadée service qui doit appeler une DLL VB6. Il n'y a pas de documentation à ce sujet VB6 DLL et ce système hérité soutient une entreprise très critique processus. p> blockQuote>
et en même temps vous dites p>
À la première fois (1º Fil), cette DLL fonctionne bien. Comme les autres threads ont besoin accès, ça commence à fournir faux Résultats. P> blockQuote>
Je ferais très certain que la gestion est consciente de la défaillance que vous voyez car le code apportant le processus métier critique est ancien et sans papiers, et est utilisé de manière à être utilisé pour qu'elle n'a jamais été utilisée, et était jamais testé pour être utilisé. Je parie que cela n'a jamais été testé pour être utilisé à partir de .net avant, l'a déjà? P>
Voici ma suggestion, et c'est semblable à quelque chose que j'ai réellement mis en œuvre: p>
La DLL VB6 prévoit d'être appelée sur un seul fil. ne vous décevez pas! em> strong> Lorsque votre service commence, demandez-vous de démarrer un fil du type approprié (je ne peux pas dire, puisque j'ai délibérément oublié tout ce que Sta / Mta stuff). Demandes de la file d'attente à ce fil d'accès à la DLL VB6. Avoir tout cet accès passer par le thread unique. P>
De cette façon, en ce qui concerne la DLL VB6, il fonctionne exactement comme il a été testé pour courir. P>
BTW, cela est légèrement différent de ce que j'ai mis en œuvre. J'ai eu un service Web, pas un service Windows. J'ai eu une dll C, pas vb6, et ce n'était pas com. Je viens de refouler tous les accès à la chose en une seule classe, puis mettez des déclarations de verrouillage autour de chacune des méthodes publiques. P>
Je ne pouvais pas être d'accord avec John plus. Comme la DLL VB6 est effectivement une boîte noire pour vous, allez avec ce qui est garanti pour être vrai. Au mieux, la DLL va soutenir un modèle de filetage d'un appartement à une seule-fileté (STA). Voir ce lien sur MSDN pour des considérations lors de l'appel d'un objet STA COM: msdn.microsoft.com/en-us/library/ms680112 (vs.85) .aspx . Pour une frappe maximale pour le Buck, vous voudrez peut-être simplement tirer parti d'un adaptateur ou d'un singleton pour réguler l'accès à un objet à un fil à la fois (comme le suggérait John). Assurez-vous de regarder votre com Interop et de faire marshaller de .NET.
Pour vous donner une réponse définitive, nous avons besoin de plus d'informations: cela fonctionne-t-il sous COM + ou non, dans l'ancien cas exécuté dans ou hors processus? Comment l'installez-vous dans un système: via REGSVR32 ou une autre moyenne?
Merci aux gars, j'ai découvert quel était le problème. Cette DLL n'était pas censée travailler avec quoi que ce soit d'autre que VB 6. Il a un bogue à l'intérieur. Il n'accepte pas les paramètres régionaux anglais sur le serveur, nous avons dû changer de langue portugaise; Langue du client. Jusqu'à présent, j'utilise le modèle de singleton et le modèle de proxy pour travailler avec ce composant hérité et il fonctionne bien.