Frage

Ich bin mit einer Multi-Thread-Windows-Dienst, der eine VB6-DLL aufrufen müssen. Es gibt keine Dokumentation zu diesem VB6 DLL und das Legacy-System unterstützt einen sehr kritischen Geschäftsprozess.

Auf den ersten Zeit (1 Thread), führt diese dll gut. Wie andere Threads zugreifen müssen, starten Sie es falsch Ergebnisse liefern.

Ich lese ein Jungs sagen:

  

"vorsichtig sein, nur an einer Sache, wenn Sie VB6 verwenden. Ihr Threading   Modell wird zu Unterstützung Wohnungen ändern müssen, wenn Sie sind   Betrieb eines Multi-Thread-Service. VB unterstützt nur mehr   Single-Threaded-Wohnungen, aber .NET läuft völlig frei Gewinde   normalerweise. Der Faden, der in die VB6 DLL aufruft muss sein   kompatibel mit dem DLL. "

Ein weiterer Mann vom Team gab mir die Idee, diese ddl in einem separaten Anwendungsdomäne zu setzen. Aber ich bin nicht sicher.

Wie können wir mit VB6 DLL arbeiten von einem Multithreaded C # Windows-Dienst-Anwendung aufgerufen?

War es hilfreich?

Lösung

Wenn die Fäden in, speichern Sie Objekte und sie später auf neue Themen Wiederverwendung? Wenn Sie können, erstellen Sie die Objekte frisch für jeden Thread. Wir haben eine Situation wie diese mit einer Datenschicht dll wir verwenden. Wenn Sie eine Verbindung auf einem Thread erstellen, kann es nicht von anderen verwendet werden. Wenn Sie eine neue Verbindung auf jedem Thread erstellen, es funktioniert gut.

Wenn es langsam ist Ihre Objekte zu erstellen, Blick auf die Klasse Threadpool und dem Threadstatic-Attribut. Threadpools recyceln den gleichen Satz von Fäden über und über die Arbeit zu tun, und Threadstatic können Sie ein Objekt erstellen, die nur für einen Thread existiert. zB

[ThreadStatic]
public static LegacyComObject myObject;

Als eine Anforderung kommt, schalten Sie ihn in einen Job und Warteschlange es in Ihrem Thread-Pool. Wenn der Job gestartet wird, prüfen, ob das statische Objekt initialisiert wird;

void DoWork()
{ 
    if (myObject == null)
    { 
        // slow intialisation process
        myObject = New ...
    }

    // now do the work against myObject
    myObject.DoGreatStuff();
}

Andere Tipps

Sie sagen

  

Ich bin mit einem Multithread-Fenster   Service, der eine VB6-DLL aufrufen müssen.   Es gibt keine Dokumentation darüber   VB6-DLL und dieses Legacy-System   unterstützt ein sehr wichtiges Geschäft   Prozess.

und zugleich Sie sagen,

  

Beim ersten Mal (1e Gewinde), hält diese dll   funktioniert gut. Wie andere Threads müssen   Zugang, starten Sie es falsch liefern   Ergebnisse.

Ich würde sehr sicher, dass das Management bewusst das Scheitern ist, dass Sie zu sehen sind, da der Code den kritischen Geschäftsprozess unterstützen alt und ohne Papiere ist, und in einer Art und Weise verwendet wird, um es nie verwendet werden sollte, und war nie verwendet werden, getestet. Ich wette, es ist auch noch nie von .NET verwendet wird getestet, oder?

Hier ist mein Vorschlag, und das ist ähnlich wie etwas, das ich tatsächlich umgesetzt haben:

Die VB6 DLL erwartet auf einem einzigen Thread aufgerufen werden. Enttäusche es nicht! Wenn Ihr Dienst gestartet wird, haben sie einen Thread des entsprechenden Typs starten (Ich kann nicht sagen, da ich bewusst alles, was STA vergessen haben / MTA Sachen). Warteschlange Anfragen an diesen Thread für den Zugang zum VB6 DLL. gehen alle haben diesen Zugang durch den einzigen Thread.

Auf diese Weise, so weit das VB6 DLL betrifft, so läuft es genau so, wie es ausgeführt wurde getestet, um.


BTW, das ist etwas anderes, als was ich umgesetzt habe. Ich hatte einen Web-Service, kein Windows-Dienst. Ich hatte eine C-DLL, nicht VB6, und es war nicht COM. Ich Refactoring nur alle Zugriff auf die Sache zu einer einzigen Klasse, dann setzen Sperre Aussagen um jede der öffentlichen Methoden.

dieser Artikel auf Multithreading Visual Basic 6 DLL bietet einen kleinen Einblick. Dort heißt es:

  

Um ein ActiveX-DLL-Projekt zu machen   multithreaded, wählen die gewünschte   Optionen auf dem Registerkarte Allgemein Einfädeln   des Dialogfelds Projekteigenschaften.

diesem Artikel es sagt sind drei mögliche Modelle zur Auswahl:

One thread of execution 
Thread pool with round-robin thread assignment 
Every externally created object is on its own thread 

Ich gehe davon aus, dass die Standard one thread of execution ist, und dass eine der beiden anderen Optionen muss ausgewählt werden.

Sie können einen Blick auf diese nehmen wollen: linky

Und hier ist ein Ausschnitt, das meine Aufmerksamkeit erregte:

  

VB6 COM-Objekte sind STA-Objekte, das heißt, sie auf einem STA-Thread ausgeführt werden müssen.   Sie haben zwei Instanzen des Objekts von zwei MTA-Threads erstellen, aber das Objekt selbst wird auf einem einzigen (KOM (OLE) erstellt) STA läuft   Faden, und den Zugang von den beiden MTA Threads gemarshallte und synchronisiert werden.   Also, was Sie tun sollten, ist, die Fäden als STA initialisiert werden, so dass jede Objekte auf seinem eigenen STA-Thread läuft ohne Serialisieren und Sie   wird gut.

     

Wie auch immer, VB Stil COM-Objekte sind immer STA. Um nun zu verhindern Wohnung Serialisieren und fädeln Schalt Sie erstellen müssen   Instanzen in STA initialisiert Wohnungen.   Beachten Sie auch, dass, wenn Sie die Option [MTAThread] -Attribut auf Main, Sie effektiv den Haupt-Thread als MTA initialisieren, wenn Sie erstellen   Instanzen von STA-Objekten aus MTA Threads COM wird ein separates (nicht verwalteten) Gewinde erstellen und als STA initialisiert wird (dies die aufgerufen wird,   Standard-STA), werden alle Anrufe an STA Objekte aus MTA Threads werden gemarshallte (und Faden Schalter anfallen), in einigen Fällen Anrufe Idispatch   wird aufgrund von IP Serialisieren Ausfälle ausfallen.   So ist die Beratung ist die Verwendung STA (und damit VB6) Objekte von kompatibelen Wohnungen nur.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top