在C#中运行程序后如何释放内存?
我有一个C#程序,我从Excel文件中读取数据,其中包含大约40000个数字。 这是我的代码的一部分:
Microsoft.Office.Interop.Excel.Application _excelApp = new Microsoft.Office.Interop.Excel.Application(); _excelApp.Visible = true; string fileName = "D:\\data.xlsx"; Workbook workbook = _excelApp.Workbooks.Open(fileName, Type.Missing); Worksheet worksheet = (Worksheet)workbook.Worksheets[1]; Range excelRange = worksheet.UsedRange; Object[,] valueArray = (object[,])excelRange.get_Value(XlRangeValueDataType.xlRangeValueDefault); int num = worksheet.UsedRange.Rows.Count; workbook.Close(false, Type.Missing); _excelApp.Quit(); for (int row = 1; row <= num; ++row) { data1.Add(Convert.ToDouble(valueArray[row, 1])); data2.Add(Convert.ToDouble(valueArray[row, 2])); }
每次运行程序时,excel文件都会显示一会儿并closures。 但是在windows的后台进程中有一些打开的excel文件,并且消耗ram,降低windows的速度。 我怎样才能完全closuresexcel文件,并退出我的代码中的内存?
谢谢。
您需要释放您使用的COM对象,以便它们可以正确closures。
试试这个代码:
var _excelApp = new Microsoft.Office.Interop.Excel.Application(); _excelApp.Visible = true; var fileName = "D:\\data.xlsx"; var workbooks = _excelApp.Workbooks; var workbook = workbooks.Open(fileName, Type.Missing); var worksheet = (Worksheet)workbook.Worksheets[1]; var excelRange = worksheet.UsedRange; Object[,] valueArray = (object[,])excelRange.get_Value(XlRangeValueDataType.xlRangeValueDefault); int num = worksheet.UsedRange.Rows.Count; Marshal.FinalReleaseComObject(excelRange); Marshal.FinalReleaseComObject(worksheet); workbook.Close(false, Type.Missing); Marshal.FinalReleaseComObject(workbook); Marshal.FinalReleaseComObject(workbooks); _excelApp.Quit(); Marshal.FinalReleaseComObject(_excelApp); for (int row = 1; row <= num; ++row) { data1.Add(Convert.ToDouble(valueArray[row, 1])); data2.Add(Convert.ToDouble(valueArray[row, 2])); }
我没有testing过这个代码,但它应该是接近的。
请注意,你绝对要做这样的代码:
var workbooks = _excelApp.Workbooks; var workbook = workbooks.Open(fileName, Type.Missing);
…你不能这样做:
var workbook = _excelApp.Workbooks.Open(fileName, Type.Missing);
…因为这留下_excelApp.Workbooks
中间对象无法释放。
你想强制垃圾收集器调用,这基本上通过调用GC.Collect()来实现。
当您调用GC.Collect时,GC将在一个单独的线程上运行每个对象的终结器。 因此,另一种记住的方法是GC.WaitForPendingFinalizers。 这个同步方法直到GC.Collect完成工作后才会返回。
例:
public void MethodUsingTonsOfMemory(){ // do memory intensive stuff GC.Collect(); GC.WaitForPendingFinalizers(); // wait for memory to be released Debug.WriteLine("Memory should be clear now"); }