Entwickler-Ecke
Basistechnologien - Interop mit Excel: Trennung vom RCW [ERROR]
C# - So 12.10.14 22:21
Titel: Interop mit Excel: Trennung vom RCW [ERROR]
Guten Abend,
ich möchte in meinem aktuellen Projekt eine Exceldatei auslesen, was auch alles klappt. Die Interaktion mit Excel habe ich in eine eigene Klasse gapackt, die IDisposable implementiert. Im Destruktor der Klasse rufe ich dann auch Dispose() auf. In Dispose() soll dann Excel wieder geschlossen werden.
Quelltext
1: 2: 3:
| Ein Ausnahmefehler des Typs "System.Runtime.InteropServices.InvalidComObjectException" ist in Test.exe aufgetreten.
Zusätzliche Informationen: Ein COM-Objekt, das vom zugrunde liegenden RCW getrennt wurde, kann nicht verwendet werden. |
Dieser Fehler tritt in der ersten Zeile der Dispose-Methode auf.
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| Excel.Application app;
public void Dispose() { app.Workbooks.Close(); app.Quit();
Marshal.FinalReleaseComObject(worksheet); Marshal.FinalReleaseComObject(app); } |
Ich verändere weder das Dokument, noch wird eine Arbeitsmappe oder gar die Excel-Instanz geschlossen.
Weiß jemand warum ich Excel nicht schließen kann? Es klappt dabei auch kein anderer Zugriff auf
app und somit kann ich auch keine Eigenschaften der
app-Instanz mehr lesen oder schreiben!
Christoph1972 - Mo 13.10.14 06:58
C# hat folgendes geschrieben : |
Weiß jemand warum ich Excel nicht schließen kann? |
Sind diese beiden Zeilen wirklich notwendig?
Marshal.FinalReleaseComObject(worksheet);
Marshal.FinalReleaseComObject(app);
Werden die FinalReleaseComObject Methoden eventuell in der app.Quit() Methode aufgerufen und somit liegt schon eine Trennung vom RCW vor? Aber die Exception dürfte irgendwie nicht in der ersten Zeile auftreten :gruebel:
Doku:
Die FinalReleaseComObject-Methode gibt den verwalteten Verweis auf ein COM-Objekt frei. Das Aufrufen dieser Methode entspricht dem Aufrufen der ReleaseComObject-Methode in einer Schleife, bis 0 (null) zurückgegeben wird.
Wenn der Verweiszähler für das COM-Objekt 0 wird, wird das COM-Objekt normalerweise freigegeben, obwohl dies von der Implementierung des COM-Objekts abhängt und von der Laufzeitzeitumgebung nicht beeinflusst werden kann. Der RCW kann jedoch immer noch vorhanden sein und auf Garbage Collection warten.
Das COM-Objekt kann nicht verwendet werden, nachdem es von seinem zugrunde liegenden RCW getrennt wurde. Wenn Sie versuchen, eine Methode auf dem RCW aufzurufen, nachdem sein Verweiszähler 0 geworden ist, wird ein InvalidComObjectException ausgelöst.
Wie bereits gefragt, sind die beiden Marshal Methoden wirklich erforderlich? Ich habe die noch nie aufgrufen und bisher gab es noch nie Probleme, klopf-klopf-klopf auf Holz :D
C# - Mo 13.10.14 08:00
Die beiden Zeilen mit dem FinalRelaseComObject() habe ich aus einem Codesample aus dem Inet. Ich habe beide Zeilen mal weggelassen aber geholfen hat es halt nicht...
liegt es vielleicht daran, dass ich Dispose() vom Destruktr aus ausrufe? Eigentlic nicht oder?
C# - Di 14.10.14 09:07
Also da ich keine Lösung gefunden habe, habe ich einen kleinen Workaround gemacht und die gesamte Verwendung der COM Objekte in eine Methode gepackt. Dann werden sie erzeugt und gleich am Ende der Methode wieder entfernt.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!