如何在 C# 中运行程序后释放内存
本文关键字:程序 释放 内存 运行 | 更新日期: 2023-09-27 18:37:25
>我有一个C#程序,在其中我从包含大约40000个数字的excel文件中读取数据。这是我代码的一部分:
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文件都会出现片刻并关闭。但是在窗口的后台进程中有一些打开的excel文件,并消耗内存并降低窗口的速度。如何完全关闭 excel 文件并从代码的内存中退出它们?
谢谢。
您需要释放您使用的 COM 对象,以便它们可以正确关闭。
试试这个代码:
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]));
}
我还没有测试过这段代码,但它应该很接近。
请注意,您绝对必须执行此类代码:
var workbooks = _excelApp.Workbooks;
var workbook = workbooks.Open(fileName, Type.Missing);
。而且你不能只这样做:
var workbook = _excelApp.Workbooks.Open(fileName, Type.Missing);
。因为这会使_excelApp.Workbooks
中间对象无法释放。
你想强制垃圾回收器调用,这基本上是通过调用 GC 来实现的。收集()。
当您调用 GC 时。收集,GC 将在单独的线程上运行每个对象的终结器。因此,要记住的另一种方法是GC。等待挂起终结器。此同步方法在 GC 之前不会返回。收集已完成其工作。
例:
public void MethodUsingTonsOfMemory(){
// do memory intensive stuff
GC.Collect();
GC.WaitForPendingFinalizers(); // wait for memory to be released
Debug.WriteLine("Memory should be clear now");
}