我有一个静态类,它实现了与Excel相关的功能(类库)。
这个dll被添加为其他应用程序的参考,我正在尝试使用这些函数。
我知道主程序终止时会释放静态对象。我可以以某种方式处理它吗?
在我的代码中,如果我调用CreateExcelDocument(excelFile)
,并且Excel的实例正在后台运行(我可以在windows的进程管理器中看到它)。但是,当我打电话给DisposeExcelDocument();
时,实例仍然存在。我怎么处理它?</ p>
我的目标是逐个打开多个Excel文件,从当前打开的文件创建图形,然后关闭并继续下一个文件。它甚至可能吗?
以下是代码:
public static class ExcelUtils
{
#region Private Members
private static Application m_excelApp;
private static Workbook m_excelWorkBook;
private static Worksheet m_excelWorkSheet;
#endregion Private Members
#region Properties
public static Worksheet ExcelWorkSheet
{
get { return m_excelWorkSheet; }
set { m_excelWorkSheet = value; }
}
#endregion Properties
#region Public Functions
public static void CreateExcelDocument(string excelFile)
{
try
{
m_excelApp = new Application();
m_excelApp.DisplayAlerts = false;
m_excelWorkBook = m_excelApp.Workbooks.Add(Type.Missing);
m_excelWorkSheet = (Worksheet)m_excelApp.ActiveSheet;
m_excelApp.DefaultSheetDirection = (int)Constants.xlLTR;
m_excelWorkSheet.DisplayRightToLeft = false;
if (excelFile.CompareTo("") != 0)
{
m_excelWorkBook = m_excelApp.Workbooks.Open(excelFile);
m_excelWorkSheet = (Worksheet)m_excelApp.Worksheets.get_Item(1);
m_excelWorkSheet.Columns.ClearFormats();
m_excelWorkSheet.Rows.ClearFormats();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return;
}
}
public static void DisposeExcelDocument()
{
try
{
m_excelApp.Quit();
ReleaseObject(m_excelWorkSheet);
ReleaseObject(m_excelWorkBook);
ReleaseObject(m_excelApp);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return;
}
}
public static void ReleaseObject(object currentObject)
{
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(currentObject);
currentObject = null;
}
catch (Exception ex)
{
currentObject = null;
Console.WriteLine(ex.ToString());
return;
}
finally
{
GC.Collect();
}
}
public static uint GetNumberOfRowsOrCols(string excelFile, bool getRows)
{
CreateExcelDocument(excelFile);
uint rowColNum = 0;
if (getRows)
rowColNum = (uint)m_excelWorkSheet.UsedRange.Rows.Count;
else
rowColNum = (uint)m_excelWorkSheet.UsedRange.Columns.Count;
DisposeExcelDocument();
return rowColNum;
}
#endregion Public Functions
}
答案 0 :(得分:1)
首先,我同意关于将其作为非静态类的评论。
但就您的问题而言,垃圾收集器不收集对象,因为您没有将null设置为类成员,而只是ReleaseObject
方法中的本地引用。
要使变更最少的类成员为空,将currentObject
参数作为ReleaseObject
传递给ref
方法,并且必须使用泛型而不是object
数据类型。所以方法将成为:
public static void ReleaseObject<T>(ref T currentObject) where T : class
并且要调用此方法,您将更改为:
ReleaseObject(ref m_excelWorkSheet);
你可以保留ReleaseObject方法的主体,但我认为不需要调用GC.Collect()
,如果你真的需要,那么最后只能从DisposeExcelDocument
调用一次,在为所有对象调用ReleaseObject
之后。