如何在 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 文件并从代码的内存中退出它们?

谢谢。

如何在 C# 中运行程序后释放内存

您需要释放您使用的 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");
}