2016-04-02 4 views
0

Ich habe ein Programm, das eine Art Ole-Verbindung verwendet, um Verbindung mit einer Cam/CAD-Software Powershape herzustellen. Es verwendet eine Klassenvariable, um eine Verbindung mit Powershape herzustellen, und seine Eigenschaften enthalten Informationen über die offenen Modelle.Wie man Klassenvariable finalisiert/zerstört

Das Problem besteht darin, dass diese Verbindung nur beendet wird, wenn die Klassenvariable abgeschlossen wird oder den Gültigkeitsbereich verlässt.

Dim powershapeRoot As New PSAutomation(Delcam.ProductInterface.InstanceReuse.UseExistingInstance) 

Dies funktioniert innerhalb Subs in Ordnung, da es außerhalb des Gültigkeitsbereiches geht, aber dieses Programm erfordert, dass Sie dies mehrmals tun, wenn Sie Daten von Powershape benötigen und es kann wieder einige Zeit in Anspruch jedes Mal macht die Verbindung nehmen. Sie können also eine globale Variable erstellen, so dass Sie die Verbindung nur einmal benötigen.

Dim powershapeRoot As New PSAutomation(Delcam.ProductInterface.InstanceReuse.UseExistingInstance) 
Powershapeglobal = powershapeRoot 

Aber jetzt geht die Variable nur aus dem Geltungsbereich, wenn das Programm geschlossen ist. Ich habe versucht zu verwenden:

Powershapeglobal.dispose 
Powershapeglobal = nothing 

Diese haben nicht geholfen und die Verbindung scheint noch zu existieren, weil die Variable noch existiert? Wie zerstörst du die Variable für immer?

+0

In VBA würden Sie „Set“ Schlüsselwort zu setzen, ein Objekt variabile auf „Nothing“ – user3598756

+0

Neben korrekt Freigabe des COM-Objekts verwenden, so dass der Zeiger nicht mehr vorhanden ist, sollten Sie auch das Objekt für GC kostenlos registrieren . Andrew Whitechapel deckt das ziemlich gut in seinem Buch ab, dem relevanten Auszug im Abschnitt über das Freigeben von COM-Objekten: https://msdn.microsoft.com/en-us/library/office/aa679807(v=office.11).aspx –

+0

Es klingt wie ein Fehler in der PSAutomation-Klasse, auf die Sie sich verlassen. Eine richtig entworfene und implementierte Klasse würde das IDisposable-Muster dafür verwenden. –

Antwort

0

In .NET werden nicht verwaltete Ressourcen nicht zerstört, wenn eine .NET-Variable den Gültigkeitsbereich verlässt. Sie werden zerstört, wenn der Garbage Collector sie aus dem Speicher entfernt, was immer dann der Fall ist, wenn der Garbage Collector das für nötig hält. Dies wird als "nicht-deterministische Finalisierung" bezeichnet, da Sie als Entwickler nicht den genauen Zeitpunkt bestimmen, zu dem Objekte fertiggestellt werden.

Um sicherzustellen, dass externe Ressourcen bereinigt werden, wenn Sie mit ihnen fertig sind, rufen Sie die Dispose() -Methode des Objekts in Frage:

:

Dim powershapeRoot As New PSAutomation(Delcam.ProductInterface.InstanceReuse.UseExistingInstance) 

Und wenn Sie die Verbindung freigeben möchten

powershapeRoot.Dispose(); 

Oder zu bekommen die Dispose automatisch geschehen, die .NET verwenden "verwenden" Anweisung:

Using powershapeRoot As New PSAutomation(Delcam.ProductInterface.InstanceReuse.UseExistingInstance) 



End Using ' Dispose is called automatically here 

Jetzt, mit COM-Objekte gibt es ein weiterer Schritt zu dem Prozess ist, müssen Sie die ReleaseComObject() Methode explizit aufrufen, wie folgt aus:

System.Marshall.ReleaseComObject(powershapeRoot); 

Und dann rufen Sie Dispose() danach. Dies ist jedoch nur erforderlich, wenn Sie explizit auf eine COM-Assembly verwiesen haben. Bei OleDB-Verbindungen ist der Aufruf von Dispose ausreichend.

https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.releasecomobject(v=vs.110).aspx

Verwandte Themen