Aslında Excel Uygulama nesnenizi temiz bir şekilde serbest bırakabilirsiniz, ancak dikkat etmeniz gerekir.
Kesinlikle eriştiğiniz her COM nesnesi için adlandırılmış bir referans tutma ve sonra açıkça onu serbest bırakma önerisi Marshal.FinalReleaseComObject()
teoride doğrudur, ancak maalesef pratikte yönetilmesi çok zordur. Biri herhangi bir yere kayıyorsa ve "iki nokta" kullanıyorsa veya hücreleri bir for each
döngü veya benzeri bir komutla yineliyorsa, referanssız COM nesneleriniz olur ve askıda kalma riskiyle karşı karşıya kalırsınız. Bu durumda, kodda nedeni bulmanın hiçbir yolu olmazdı; büyük bir proje için neredeyse imkansız olabilecek bir görevi tüm kodunuzu gözden geçirmeniz ve umarım sebebi bulmanız gerekir.
İyi haber şu ki, kullandığınız her COM nesnesine adlandırılmış bir değişken başvurusu sağlamak zorunda değilsiniz. Bunun yerine, başvuru içermediğiniz tüm (genellikle küçük) nesneleri serbest bırakmak ve sonra adlandırılmış değişken başvurusunu tuttuğunuz nesneleri açıkça serbest bırakmak için GC.Collect()
ve sonra çağrı yapın GC.WaitForPendingFinalizers()
.
Ayrıca adlandırılmış referanslarınızı önem sırasının tersine de bırakmanız gerekir: önce nesneleri, sonra çalışma sayfalarını, çalışma kitaplarını ve son olarak Excel Uygulama nesnenizi aralıklandırın.
Örneğin, adlı bir Range nesnesi değişkenine, adlı xlRng
bir Çalışma Sayfası değişkenine, adlı xlSheet
bir Çalışma Kitabı değişkenine xlBook
ve adlı bir Excel Uygulama değişkenine sahip olduğunuzu varsayarak, xlApp
temizleme kodunuz aşağıdaki gibi görünebilir:
// 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);
Çoğu kod örneğinde, COM nesnelerini .NET'ten temizlemek için görürsünüz ve GC.Collect()
ve GC.WaitForPendingFinalizers()
çağrıları aşağıdaki gibi TWICE yapılır:
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
Ancak, nesnelerin tüm grafiğinin sonlandırma kuyruğunda yükseltilmesine neden olan sonlandırıcıları kullanan Office için Visual Studio Araçları (VSTO) kullanmadığınız sürece bu gerekli olmamalıdır. Bu tür nesneler bir sonraki çöp toplama işlemine kadar serbest bırakılmaz . Eğer VSTO kullanmıyorsanız Ancak, aramak gerekir GC.Collect()
ve GC.WaitForPendingFinalizers()
sadece bir kez.
Açıkça aramanın GC.Collect()
hayır-hayır olduğunu biliyorum (ve kesinlikle iki kez yapmak çok acı verici geliyor), ama dürüst olmak gerekirse, bunun hiçbir yolu yok. Normal işlemler sayesinde, başvurmadığınız gizli nesneler oluşturacaksınız, bu nedenle, arama dışında başka bir yolla serbest bırakamazsınız GC.Collect()
.
Bu karmaşık bir konu, ama gerçekten de hepsi bu kadar. Temizleme yordamınız için bu şablonu oluşturduktan sonra, sarıcıya ihtiyaç duymadan normal olarak kodlayabilirsiniz. :-)
Burada bu konuda bir öğretici var:
VB.Net / COM Interop ile Office Programlarını Otomatikleştirme
VB.NET için yazılmıştır, ancak bundan vazgeçmeyin, prensipler C # ile aynıdır.