Autor Beitrag
C#
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 561
Erhaltene Danke: 65

Windows 10, Kubuntu, Android
Visual Studio 2017, C#, C++/CLI, C++/CX, C++, F#, R, Python
BeitragVerfasst: So 12.10.14 22:21 
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.
ausblenden 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.
ausblenden 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!

_________________
Der längste Typ-Name im .NET-Framework ist: ListViewVirtualItemsSelectionRangeChangedEventHandler
Christoph1972
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 690
Erhaltene Danke: 16


VS2015 Pro / C# & VB.Net
BeitragVerfasst: Mo 13.10.14 06:58 
user profile iconC# hat folgendes geschrieben Zum zitierten Posting springen:

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

_________________
Gruß
Christoph
C# Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 561
Erhaltene Danke: 65

Windows 10, Kubuntu, Android
Visual Studio 2017, C#, C++/CLI, C++/CX, C++, F#, R, Python
BeitragVerfasst: 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?

_________________
Der längste Typ-Name im .NET-Framework ist: ListViewVirtualItemsSelectionRangeChangedEventHandler
C# Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 561
Erhaltene Danke: 65

Windows 10, Kubuntu, Android
Visual Studio 2017, C#, C++/CLI, C++/CX, C++, F#, R, Python
BeitragVerfasst: 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.

_________________
Der längste Typ-Name im .NET-Framework ist: ListViewVirtualItemsSelectionRangeChangedEventHandler