2008-09-04 5 views
1

Wir haben eine Drittanbieter-DLL, die in unserem Web-Service in IIS6 verwendet wird. Das Problem ist, dass die Ausnahme AccessViolationException einmal ausgelöst wird, wenn diese DLL in Arbeitsspeicher geladen wird, wenn ein Thread, der anders als der erstellt wird, versucht, Code innerhalb der DLL auszuführen. Der Worker-Prozess ist multi-threaded und jeder Aufruf an den Webdienst wird einen zufälligen Thread aus dem Pool abrufen. Wir haben versucht, es aus dem Speicher zu entladen und es jedes Mal neu zu laden, wenn wir es brauchten, aber ich denke, nur das Frontend ist .Net und der Rest ist nicht verwaltet, so dass es nie wirklich komplett aus dem Speicher entladen wird. Wir verwenden VB und .Net 2.0. Irgendwelche Vorschläge?Wie kann sichergestellt werden, dass derselbe Thread zum Ausführen von Code in IIS verwendet wird?

(Antwort auf Rob Walker)

Wir dachten über einen neuen Thread erstellen und verwendet es die DLL zu rufen, aber wie machen wir das Gewinde sitzt und für Anrufe warten? Wie delegiert Sie den Aufruf an den Thread, ohne dass die Dispatcher-Klasse von .Net 3.0 bereitgestellt wird? Es könnte funktionieren, ein verborgenes Formular zu erstellen und es in eine Nachrichtenschleife einzufügen. Und dann könnten wir die Invoke() - Methode des Formulars aufrufen. Ich kann jedoch viele Probleme feststellen, wenn wir ein Formular in einem von IIS gehosteten Webdienst erstellen.

Antwort

1

Ich habe über eine Klasse in. NET 3.0 namens Dispatcher gelesen, mit dem Sie einen Thread in eine Schleife setzen und dann die Methode Invoke() mit einem Delegaten aufrufen können, um eine Methode mit dem Thread auszuführen. Diese Lösung funktioniert jedoch nicht, wenn Sie nicht auf .Net 3.0 aktualisieren können. Eine andere Lösung wäre, die Drittanbieter-DLL in einer anderen Anwendung auf dem Server zu hosten und eine Form von Remoting für den Zugriff darauf zu verwenden. Möglicherweise haben Sie jedoch weiterhin ein Problem mit dem Remoting, da es sich ähnlich wie IIS verhält und außerdem einen zufälligen Thread auswählt, um den Code auszuführen. Um dies zu umgehen, können Sie einen Wrapper um die DLL legen und ihn verwenden, um die Aufrufe an den Benutzeroberflächenthread mithilfe der Invoke() - Methode des Formulars zu delegieren.

1

Ich denke, Sie müssen sich mit einem Wrapper-Thread, der alle Aufrufe an die DLL behandelt, und beschäftigt sich mit der Serialisierung.

Dieser Thread befindet sich außerhalb des verwalteten Threadpools, Sie können also die Lebensdauer des Threads steuern. Aber selbst dies wäre nicht idiotensicher, wenn Sie IIS nicht daran hindern könnten, die Anwendungsdomäne neu zu starten, in der sich Ihr Webdienst befindet.

Sie müssen sich auch Gedanken darüber machen, was passiert, wenn zwei Web-Service-Anfragen gleichzeitig eingehen. Ist jeder Aufruf in der DLL eigenständig oder müssen Sie alle mit einer einzelnen Webdienstanforderung verknüpften Aufrufe gruppieren, bevor Sie andere Anforderungen bearbeiten?

0

Sie könnten einen Dienst erstellen, der die zusätzliche DLL hostet. Durch das Remoting greifen Sie auf den Dienst zu. Dadurch werden die Aufrufe an den Thread gesendet, der die DLL verwaltet.

Auf diese Weise haben Sie die Kontrolle über den Thread, der die DLL aufruft, und über die Lebensdauer des Threads.

0

Ich bin ein wenig eingerostet, aber Sie könnten versuchen, Aufrufe an die DLL in einem COM-Objekt mit einem einzelnen Threads zu umhüllen. Dies würde sicherstellen, dass alle Aufrufe den Windows-Nachrichten-Thread des COM-Objekts durchlaufen. Ich denke, dass Sie die Komponente in einer Serveranwendung innerhalb der Komponentendienste registrieren müssen, um dies zu tun.

0

Können Sie die DLL in verschiedenen Threads als verschiedene Instanzen ausführen? Wie thread1 erstellt eine Instanz dieser Drittanbieter-DLL, und thread2 auch, aber solange thread1 nicht versucht, thread2-Instanz zu verwenden, wird diese Ausnahme nicht ausgelöst? Wenn dies der Fall ist, entlädt .Net nie einen Code, sobald dieser geladen ist. Wenn Sie eine Assembly laden und sie dann entfernen, befindet sie sich immer noch in diesem Anwendungspool. Wenn Sie mehrere Instanzen gleichzeitig erstellen können, können Sie sie in einem separaten App-Pool, den Sie pro Anfrage steuern, laden und dann den App-Pool entladen. Die Leistung könnte jedoch fallen.

Verwandte Themen