Laden...

Marshal.FinalReleaseComObject - Objekt lebt trotzdem weiter

Erstellt von Mallett vor 9 Jahren Letzter Beitrag vor 9 Jahren 892 Views
M
Mallett Themenstarter:in
171 Beiträge seit 2012
vor 9 Jahren
Marshal.FinalReleaseComObject - Objekt lebt trotzdem weiter

Hallo zusammen,

ich habe gerade ein Problem untersucht, bei dem ich nicht sicher bin, wie das zu bewerten ist:

Kunde baut eine Testanwendung (Consolen-Applikation) mit C# - dort bindet er über einen Verweis eine Siemens-DLL als COM-Objekt ein.

Aus der DLL instanziiert er jetzt ein Objekt über COM, im Process-Explorer sieht man, wie ein Prozess als untergeordneter Prozess der Consolenanwendung auf geht.

So weit so gut. Ohne sonst irgendwas mit dem Objekt zu machen ruft er jetzt Marshal.FinalReleaseCOMObject auf das Objekt auf.

Erwartung: Das Objekt wird frei gegeben und verschwindet aus Process-Explorer

Tatsächlich: Das Objekt ist zwar von C# aus nicht mehr ansprechbar, im Process-Explorer lebt der Prozess aber weiter.

Untersuchung des Prozesses im Process-Explorer zeigt jetzt unter View->Handles zwei noch laufende Threads an.

Meine Vermutung wäre jetzt, dass die Komponente intern schlampig programmiert ist und beim Aufruf von Release() nicht korrekt aufräumt. Kann man davon ausgehen, oder gibt es noch weitere Möglichkeiten?

Danke

T
708 Beiträge seit 2008
vor 9 Jahren

Meine Vermutung wäre jetzt, dass die Komponente intern schlampig programmiert ist und beim Aufruf von Release() nicht korrekt aufräumt. Kann man davon ausgehen, oder gibt es noch weitere Möglichkeiten?

Hallo Mallett,

dass muss es nicht automatisch heißen. Vielleicht ist das ja sogar (aus irgendwelchen Gründen so gewünscht).
Diese Komponente kann ja im Hintergrund Threads starten oder weitere DLL´s nachladen.
Falls es eine Beschreibung dazu gibt, wird dort sicherlich drinstehen, wie man das Objekt korrekt Disposed (Erwarte ich jetzt einfach mal von einem Hersteller wie Siemens). Je nach dem welche Komponente das ist, kann es ja sogar immens wichtig sein, bestimmte Reihenfolgen beim Beenden einzuhalten.
Man erinnere sich an die iranische Zentrifugensteuerung in der Urananreicherungsanlage. Die sind nicht korrekt runtergefahren 😉

M
Mallett Themenstarter:in
171 Beiträge seit 2012
vor 9 Jahren

Das Problem daran ist halt, dass es nie beendet wird. Wenn es noch eine Zeit lang X irgendwas macht, bevor es verschwindet, das wäre ja ok. Aber es bleibt eben permanent lebendig. Wird das Ganze später ein zweites Mal geöffnet, hat man schon zwei Prozesse usw.

Siemens hat laut Kunde vorgeschlagen, einfach die .NET.exe zu beenden - das will der Kunde aber gerade nicht. Daher die Anforderung, externen Prozess aufräumen, wenn nicht mehr benötigt.

Ich könnte jetzt noch vorschlagen, das Dingen einfach per Process-Klasse zu killen, aber so richtig toll scheint mir das auch nicht zu sein.

16.835 Beiträge seit 2008
vor 9 Jahren

Wie in der Beschreibung von FinalReleaseComObject zu entnehmen garantiert diese Methode nicht die Ressourcenfreigabe.
Beim Aufruf von FinalReleaseComObject wird einzig und allein dem Betriebssystem mitgeteilt, dass .NET dieses Objekt aktuell nicht mehr braucht (Reference-Counter wird auf 0 gesetzt). Wann das Objekt tatsächlich abgeräumt wird, das entscheidet das OS selbst; spätestens jedoch beim Beenden des Main-Threads.

Wenn es jedoch nie freigegeben wird, dann deutet das i.d.R. auf ein Leak hin.

Les Dir dazu auch Proper Way of Releasing COM Objects in .NET durch.

J
641 Beiträge seit 2007
vor 9 Jahren

was für eine komponente von siemens wollt ihr den da verwenden? vielleicht gibts noch einen anderen weg?

cSharp Projekte : https://github.com/jogibear9988

Gelöschter Account
vor 9 Jahren

Hallo Mallett,

Wenn eine simple Instanzierung und anschliessende zerstörung nicht dazu führt das der Prozess sich nicht wieder beendet ist das entweder ein Fehler vom Dritthersteller oder absichtlich so gewollt. Was passiert denn wenn du den Test sofort wiederholst? Wird dann ein neuer Prozess aufgemacht? Wenn ja, liegt nach Lage der Dinge ein Fehler vor, ansonsten ist es ein beabsichtiges Verhalten.

M
Mallett Themenstarter:in
171 Beiträge seit 2012
vor 9 Jahren

Hallo,

sorry für die späte Antwort.

Ja, wenn ich ständig das Objekt initialisiere und dann wieder frei gebe, wird jedes Mal ein neuer Prozess auf gemacht. Deswegen gehe ich auch mal davon aus, dass die Release Logik in der Komponente entweder garnicht vorhanden oder fehlerhaft ist.

Der Hersteller der Komponente hat auf Nachfrage wie gesagt auch empfohlen, den Prozess über ProcessInfo zu beenden, das deutet eigentlich in dieselbe Richtung.

Trotzdem Danke für die Antworten.

49.485 Beiträge seit 2005
vor 9 Jahren

Hallo Mallett,

Der Hersteller der Komponente hat auf Nachfrage wie gesagt auch empfohlen, den Prozess über ProcessInfo zu beenden

möglicherweise würde es reichen, die COM-Komponente in eine eigene AppDomain zu packen und diese zu entladen.

herbivore