我知道我应该在使用互操作时释放COM对象。在开发和加载项时,例如Excel会有所不同吗?这是我的循环,我很想知道Marshal.ReleaseComObject
是否有必要?
foreach (var sheet in results.Sheets)
{
var newSheet = workbook.AddSheet();
newSheet.SetSheetTabColor(sheet.TabColor);
newSheet.SetSheetName(sheet.TabName);
newSheet.Cells.SetFont("Calibri", 8);
newSheet.FreezeRow(1);
var endRow = sheet.Data.GetUpperBound(0) + 1;
var endColumn = sheet.Data.GetUpperBound(1) + 1;
var writeRange = newSheet.SetWriteRange(1, 1, endRow, endColumn);
writeRange.Value2 = sheet.Data;
newSheet.AutoFitColumns();
newSheet.RemoveColumn(1);
Marshal.ReleaseComObject(newSheet);
}
另外,我创建了一个带扩展方法的库。一个例子是workbook.AddSheet()
AddSheet
看起来像这样:
public static Worksheet AddSheet(this Microsoft.Office.Interop.Excel.Workbook workbook)
{
var sheets = workbook.Sheets;
return sheets.Add(After: sheets[sheets.Count]);
}
由于我从sheets
访问workbook.Sheets
,我是否必须释放此对象?如果是这样,因为我返回工作表?我回来之前不能放行?
这可能是一个愚蠢的问题,但如果Marshal.ReleaseComObject
在foreach范围内不是必需的,即使它仍然存在,它是否会受到伤害?
仅当您需要及时或按特定顺序控制COM对象的生命周期时,才使用Marshal.ReleaseComObject
。对于COM对象的随意使用,我建议你不要使用这种方法。
检查here
此方法用于显式控制从托管代码使用的COM对象的生存期。您应该使用此方法释放持久保存对资源的引用的基础COM对象,或者必须以特定顺序释放对象。
关于你的第二个问题
由于我从workbook.Sheets访问工作表,我是否必须发布此对象?如果是这样,因为我返回工作表?我回来之前不能放行?
.NET中的COM实现使用引用计数机制来检测是否使用了对象,所以不需要显式释放任何内容。该框架对此负有责任。
注意:使用适当的.Close
(适用于Workbook),. Quit
(适用于应用程序)方法来正确释放resurces。当你在应用程序对象上使用.Quit
()时,你将关闭windows中的excel进程(这将释放所有资源),并在工作簿上关闭.Close
()以释放文件锁...等特定的excel文件。