Anda benar-benar dapat melepaskan objek Aplikasi Excel Anda dengan bersih, tetapi Anda harus berhati-hati.
Saran untuk mempertahankan referensi bernama untuk benar-benar setiap objek COM yang Anda akses dan kemudian secara eksplisit melepaskannya melalui Marshal.FinalReleaseComObject()
teori, tetapi, sayangnya, sangat sulit untuk dikelola dalam praktiknya. Jika seseorang pernah tergelincir di mana saja dan menggunakan "dua titik", atau mengulangi sel melalui for each
loop, atau perintah sejenis lainnya, maka Anda akan memiliki objek COM yang tidak direferensikan dan berisiko hang. Dalam hal ini, tidak akan ada cara untuk menemukan penyebabnya dalam kode; Anda harus meninjau semua kode Anda dengan mata dan mudah-mudahan menemukan penyebabnya, tugas yang hampir mustahil untuk proyek besar.
Berita baiknya adalah Anda tidak harus mempertahankan referensi variabel bernama untuk setiap objek COM yang Anda gunakan. Sebaliknya, panggil GC.Collect()
dan kemudian GC.WaitForPendingFinalizers()
untuk melepaskan semua objek (biasanya minor) yang tidak Anda pegang referensi, dan kemudian secara eksplisit melepaskan objek yang Anda pegang referensi variabel bernama.
Anda juga harus merilis referensi nama Anda dalam urutan terbalik kepentingan: objek rentang pertama, lalu lembar kerja, buku kerja, dan akhirnya objek Aplikasi Excel Anda.
Misalnya, dengan asumsi bahwa Anda memiliki variabel objek Range bernama xlRng
, variabel Worksheet bernama xlSheet
, variabel Workbook bernama xlBook
dan variabel Aplikasi Excel bernama xlApp
, maka kode pembersihan Anda bisa terlihat seperti berikut:
// Cleanup
GC.Collect();
GC.WaitForPendingFinalizers();
Marshal.FinalReleaseComObject(xlRng);
Marshal.FinalReleaseComObject(xlSheet);
xlBook.Close(Type.Missing, Type.Missing, Type.Missing);
Marshal.FinalReleaseComObject(xlBook);
xlApp.Quit();
Marshal.FinalReleaseComObject(xlApp);
Dalam sebagian besar contoh kode Anda akan melihat untuk membersihkan objek COM dari .NET, GC.Collect()
dan GC.WaitForPendingFinalizers()
panggilan dibuat DUA KALI seperti pada:
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
Namun, ini tidak diperlukan, kecuali jika Anda menggunakan Visual Studio Tools for Office (VSTO), yang menggunakan finalizers yang menyebabkan seluruh grafik objek dipromosikan dalam antrian finalisasi. Benda-benda seperti itu tidak akan dirilis sampai pengumpulan sampah berikutnya . Namun, jika Anda tidak menggunakan VSTO, Anda harus dapat menelepon GC.Collect()
dan GC.WaitForPendingFinalizers()
sekali saja.
Saya tahu bahwa menelepon secara eksplisit GC.Collect()
adalah tidak-tidak (dan tentu saja melakukannya dua kali terdengar sangat menyakitkan), tetapi tidak ada jalan lain, jujur saja. Melalui operasi normal, Anda akan menghasilkan objek tersembunyi yang tidak Anda pegang referensi sehingga tidak dapat dilepaskan melalui cara lain selain menelepon GC.Collect()
.
Ini adalah topik yang kompleks, tetapi ini adalah segalanya. Setelah Anda membuat templat ini untuk prosedur pembersihan, Anda dapat membuat kode secara normal, tanpa perlu pembungkus, dll. :-)
Saya punya tutorial tentang ini di sini:
Mengotomatiskan Program Office dengan VB.Net / COM Interop
Ini ditulis untuk VB.NET, tetapi jangan ditunda karena itu, prinsip-prinsipnya persis sama seperti ketika menggunakan C #.