我一直在从事一个相当复杂的C#VSTO项目,该项目在Excel中完成很多的不同工作。但是,我最近偶然发现了一个我不知道如何解决的问题。恐怕将整个项目放在这里会使我的问题变得过于复杂并使每个人困惑,所以这就是问题所在:
//this is a simplified version of Range declaration which I am 100% confident in
Range range = worksheet.Range[firstCell, lastCell]
range.Formula = array;
//where array is a object[,] which basically contains only strings and also works perfeclty fine
应该将[,]数组插入到以前用于较小Excel书籍的Excel范围的最后一行,但是现在对于具有System.OutOfMemoryException: Insufficient memory to continue the execution of the program
的较大书籍会崩溃,我也不知道为什么,因为以前对于一个维度,最多可使用500个以上元素的数组,而现在包含400个以下元素的数组会崩溃。此外,崩溃时的RAM使用量约为1.2GB,我知道该项目能够在RAM使用量约为3GB的情况下完美运行。
我已经尝试了以下操作:逐行插入此数组,然后逐个插入该数组,在每次插入一行或一个单元格之前调用GC.Collect(),但是仍然会失败,并显示System.OutOfMemoryException
。
因此,对于解决此问题或确定错误可能隐藏在哪里的任何帮助,我将不胜感激,因为我无法理解为什么它拒绝为长度较短(但内容可能稍大一些)的数组工作的原因RAM使用量为1.2GB,大约是以前的1/3。谢谢!
编辑
我在评论中被告知,上面的代码可能太稀疏了,所以这里是一个更详细的版本(我希望它不会太混乱):
List<object[][]> controlsList = new List<object[][]>();
// this list is filled with a quite long method calling a lot of other functions
// if other parts look fine, I guess I'll have to investigate it
int totalRows = 1;
foreach (var control in controlsList)
{
if (control.Length == 0)
continue;
var range = worksheet.GetRange(totalRows + 1, 1, totalRows += control.Length, 11);
//control is an object[n][11] so normally there are no index issues with inserting
range.Formula = control.To2dArray();
}
//GetRange and To2dArray are extension methods
public static Range GetRange(this Worksheet sheet, int firstRow, int firstColumn, int lastRow, int lastColumn)
{
var firstCell = sheet.GetRange(firstRow, firstColumn);
var lastCell = sheet.GetRange(lastRow, lastColumn);
return (Range)sheet.Range[firstCell, lastCell];
}
public static Range GetRange(this Worksheet sheet, int row, int col) => (Range)sheet.CheckIsPositive(row, col).Cells[row, col];
public static T CheckIsPositive<T>(this T returnedValue, params int[] vals)
{
if (vals.Any(x => x <= 0))
throw new ArgumentException("Values must be positive");
return returnedValue;
}
public static T[,] To2dArray<T>(this T[][] source)
{
if (source == null)
throw new ArgumentNullException();
int l1 = source.Length;
int l2 = source[0].Length(1);
T[,] result = new T[l1, l2];
for (int i = 0; i < l1; ++i)
for (int j = 0; j < l2; ++j)
result[i, j] = source[i][j];
return result;
}
我不是100%确定正确地找到了它,但是问题似乎出在Interop.Excel / Excel的限制和我尝试插入的公式的长度之内:只要长度接近8k个字符,这是很接近的到公式内容的Excel限制时,会弹出System.OutOfMemoryException
。当我选择省略冗长的公式时,该程序开始正常运行。