COM Proxy Objekte in .NET
Sofern Sie bereits mit den Primary Interop Assemblies von Microsoft gearbeitet
haben wissen Sie das Excel auf einer COM Architektur basiert. Das bedeutet, sie
beziehen in ihrer Anwendung COM Proxy Objekte für deren Freigabe sie
verantwortlich sind. Betrachten sie dazu folgendes Codebeispiel:
// Exemplarisches Vorgehen für das erstellen
eines neuen Workbook und durchlaufen seiner Worksheets mit den Primary Interop
Assemblies
using Office =
Microsoft.Office.Core;
using Excel =
Microsoft.Office.Interop.Excel;
Excel.
Application application = new Microsoft.Office.Interop.Excel.Application();Marshal.ReleaseComObject(sheets);
Marshal.ReleaseComObject(book);
Marshal.ReleaseComObject(books);
application.Quit();
Marshal.ReleaseComObject(application);
Wie sie vermutlich wissen müssen Sie jedes COM Proxy Objekt durch die Funktion
ReleaseComObject freigeben.
Sie signalisieren dem COM Server also Excel damit das Sie das Objekt nicht mehr
benötigen. Würden Sie das Objekt nicht freigeben hält der COM Server es
weiterhin im Speicher auch wenn Sie die Anwendung längst geschlossen haben und
Ihr Programm beendet ist. Sie hätten ein Memory Leak erzeugt und ihre erzeugte
Excel Instanz wäre immer noch als aktiver Prozess im Windows Task Manager zu
sehen.
Aufgrund dieser Verhaltenweise ist es notwendig jedes benutze Objekt explizit zu
speichern um es nach der Benutzung wieder freigeben zu können. Wie sie im obigen
Codebeispiel sehen speichern wir die Worksheets Auflistung von book explizit in
einer lokalen Variable. Ein durchaus verbreitetes aber falsches Vorgehen ist die
Nutzung ohne explizite vorherige Speicherung. Betrachten sie dazu folgendes
Codebeispiel:
// Exemplarische falsche Vorgehensweise im Umgang mit Primary Interop
Assemblies
Durch das direkte Nutzen der Worksheets Auflistung haben wir keine Möglichkeit
dafür später die Funktion ReleaseComObject
aufzurufen. Der COM Server hält die Auflistung nun weiterhin im
Speicher bereit und wartet (vergebens) das Sie ihm die Freigabe signalisieren.
Verwenden Sie im Umgang mit den Primary Interop Assemblies nie COM Proxy Objekte
ohne sie explizit vorher zu speichern! Dadurch ergeben sich natürlich folgende
Nachteile:
- Sie müssen jederzeit bedenken alle Objekte stets wieder freigeben zu müssen,
untypisch in einer managed Umgebung.
- Ihr Code wird durch die expliziten Speicherungen und Freigabender COM Proxy
Objekte schnell aufgebläht und unleserlich.
COM Proxy Objekte mit LateBindingApi.Excel
Siehe dazu: Tutorial01.csproj
Wenn Sie LateBindingApi.Excel nutzen haben Sie
die Wahl ob und wie Sie COM Proxy Objekte behandeln. Sie können jedes Objekt so
wie bei den Primary Interop Assemblies selbst freigeben, dazu benutzen sie die
Funktion Dispose() oder sie nutzen die
hierarchische Referenzverwaltung. Betrachten Sie dazu folgendes Codebeispiel:
// Exemplarisches Vorgehen für das erstellen eines neuen Workbook und
durchlaufen seiner Worksheets mit LateBindingApi.Excel
Excel.
Application application = new Excel.Application();foreach
(Excel.Worksheet sheet in book.Worksheets)application.Quit();
application.Dispose();
Der Code erzeugt zuerst eine Instanz der Klasse
Excel.Application. Alle weiteren Objekte werden über diese Instanz oder
untergeordnete Objekte der Instanz erstellt. Mit dem Aufruf von
Dispose() in der letzten Codezeile wird die Instanz von
Excel.Application und damit auch alle
untergeordneten Objekte freigegeben. Betrachten sie dazu ein weiteres
Codebeispiel:
Excel.
Application application = new Excel.Application();foreach
(Excel.Worksheet sheet in book.Worksheets)
Durch das erstellen von Excel.Workbook
book und das anschliessende beschreiben der Worksheets entsteht in der
hierarchischen Referenzverwaltung folgender Objekt Baum:
- application
- Workbooks
- book
- Worksheets
- sheet
- Range
- Range
- Range
- sheet
- Range
- Range
- Range
- sheet
- Range
- Range
- Range
Mit dem Aufruf von book.Dispose() geben sie alle darunter verwalteten Objekte
wieder frei. Sie müssen keine Variablen zwischenspeichern und können
auch Enumeratoren direkt benutzen, dies hält ihren Code kleiner und
übersichtlicher.
Siehe dazu: Tutorial01.csproj