Насколько я знаю, в COM Interop, если мы пересекаем границу .NET/COM, мы получаем прирост внутреннего счетчика RCW. Так что я создал книгу VSTO Excel (2013) приложение и побежал код:COM Interop RCW Reference Count для объекта диапазона Excel
private void RCWWorkbooks()
{
Excel.Workbooks wbs = Application.Workbooks;Excel.Workbook book1 = wbs[1];
Excel.Workbook book2 = wbs[1];
Excel.Workbook book3 = wbs[1];
Debug.WriteLine("Book3:= " + Marshal.ReleaseComObject(book3));
Debug.WriteLine("Book2:= " + Marshal.ReleaseComObject(book2));
Debug.WriteLine("Book1:= " + Marshal.ReleaseComObject(book1));
}
И выход, как я ожидал:
Book3:=2
Book2:=1
Book1:=0
т.е. у нас есть 3 ссылки, общее кол-3 в RCW, который каждый получает уменьшается на 1, когда я призываю ReleaseCOMObject
Я сделал то же самое для испытания рабочего листа: на этот раз я получаю результаты:
private void RCWSheets()
{
Excel.Sheets wks = Application.Workbooks[1].Worksheets;
Excel.Worksheet sht1 = wks[1];
Excel.Worksheet sht2 = wks[1];
Excel.Worksheet sht3 = wks[1];
Debug.WriteLine("Sheet3:= " + Marshal.ReleaseComObject(sht3));
Debug.WriteLine("Sheet2:= " + Marshal.ReleaseComObject(sht2));
Debug.WriteLine("Sheet1:= " + Marshal.ReleaseComObject(sht1));
}
И результат был не таким, каким я ожидал.
Sheet3:=3
Sheet2:=2
Sheet1:=1
Не могу решить, почему sheet3: = 3. Я ожидал, что это будет 2.
Далее я попробовал тест диапазона с помощью следующего кода:
private void RCWRanges()
{
Excel.Worksheet sht = Application.Workbooks[1].Worksheets[1];
Excel.Range r1 = sht.Range["A1"];
Excel.Range r2 = sht.Range["A1"];
Excel.Range r3 = sht.Range["A1"];
Debug.WriteLine("Range3:= " + Marshal.ReleaseComObject(r3));
Debug.WriteLine("Range2:= " + Marshal.ReleaseComObject(r2));
Debug.WriteLine("Range1:= " + Marshal.ReleaseComObject(r1));
}
Опять же, выход не было, как я ожидал:
Range3:=0
Range2:=0
Range1:=0
Так что мой вопросы:
- Почему листовой тест вернул дополнительный счет. Он вернулся 3, где я ожидал двух.
- Почему тест диапазона возвращал 0 для всех отсчетов ссылок? Это говорит о том, что запрос диапазона не пересекает барьер .NET/COM.
Благодаря
Довольно хороший пример, почему ручное управление памятью является такой ошибкой. Объектная модель автоматизации Excel слишком сложна, чтобы получить право на это. Обратите внимание на свойство ActiveSheet в объекте Application, которое также может иметь ссылку на первый лист. Workbook и WorkSheet являются дорогостоящими объектами, Excel избегает создания дополнительных экземпляров. Диапазоны нет. Не пишите такой код, вы всегда будете ошибаться. Сборщик мусора никогда не делает. –
Спасибо, Ханс. Могу я просто спросить, знаете ли вы какую-либо документацию в любом месте, где объясняется бит Range, о чем вы говорили. Я ничего не могу найти по этому поводу. то есть, как вы знаете, что объекты диапазона обрабатываются таким образом. – PaulG
Нет такой документации. Единственная причина, по которой я знаю, это то, что вы только что сказали мне. –