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();
Excel.
Workbooks books = application.Workbooks;
Excel.
Workbook book = books.Add(Missing.Value);
Excel.
Worksheets sheets = (Excel.Worksheets)book.Worksheets;

 

 

foreach (Excel.Worksheet sheet in sheets)
{
   
Console.WriteLine(sheet.Name);
   
Marshal.ReleaseComObject(sheet);
}

Marshal.ReleaseComObject(sheets);
Marshal.ReleaseComObject(book);
Marshal.ReleaseComObject(books);

application.Quit();

 


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

foreach (Excel.Worksheet sheet in book.Worksheets)
{
   
Console.WriteLine(sheet.Name);
   
Marshal.ReleaseComObject(sheet);
}


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

using Office = LateBindingApi.Office;
using Excel = LateBindingApi.Excel;

Excel.

Application application = new Excel.Application();
Excel.
Workbook book = application.Workbooks.Add();

foreach

(Excel.Worksheet sheet in book.Worksheets)
{
   
Console.WriteLine(sheet.Name);
}

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:
 

 

// Exemplarisches Vorgehen für das erstellen eines neuen Workbook und beschreiben seiner Worksheets mit LateBindingApi.Excel
using Office = LateBindingApi.Office;
using Excel = LateBindingApi.Excel;

Excel.

Application application = new Excel.Application();
Excel.
Workbook book = application.Workbooks.Add();

foreach

(Excel.Worksheet sheet in book.Worksheets)
{
   
for(int i=1;i<=3;i++)
        sheet.Cells[1,i].Value =
"exampleString";
}
book.Dispose();

application.Quit();
application.Dispose();


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

Marshal.ReleaseComObject(application);

Last edited Feb 5, 2011 at 10:40 AM by SebastianDotNet, version 1

Comments

No comments yet.