【发布时间】:2013-12-10 13:33:13
【问题描述】:
我有一个实现 Excel 相关函数的静态类(类库)。
添加此 dll 作为对其他应用程序的引用,我正在尝试使用这些功能。
我知道当主程序终止时会释放静态对象。我可以以某种方式处理它吗?
在我的代码中,如果我调用CreateExcelDocument(excelFile),并且 Excel 实例正在后台运行(我可以在 Windows 的进程管理器中看到它)。但是,当我调用DisposeExcelDocument(); 时,实例仍然存在。我该如何处理它?
我的目标是逐个打开多个 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
}
【问题讨论】:
-
您是否考虑过不将这些作为静态变量开始?是的,如果你真的想要,你可以处理它们——但将它们作为实例变量会更干净,你可以让调用者根据需要创建单个实例或多个实例。毕竟,它固有地不是静态的。
-
是的,但是我不能从外部调用公共函数,它们应该是静态的。
-
嗯,是的,您还需要更改其余代码 - 但这将是重构它以改进它。
-
看起来您希望对
ReleaseObject的调用也对null对象进行调用,但是这不会使持有对它的引用的静态类变量为空。它当前所做的只是将对象的方法范围引用清空,而不是类范围引用。这可能就是您的实例“保留”的原因。您也无需致电GC.Collect。也就是说,我还建议进行重构以减少对静态全局对象的依赖,但这并不总是可能/可行的。 -
您能否解释一下如何更改代码,以便我能够从外部项目调用位于类库中的非静态函数?
标签: c# excel object static dispose