2012-10-10 34 views
-1

我试图将电子表格数据捕获到二维数组中。我正在使用VSTO。OutofMemory异常对象数组大小

int rc = 1048576; 
int cc = 1638; 

string[,] arr = new string[rc, cc]; 

最后一行抛出内存不足异常。我想告诉用户只能显示'X'元素的信息。

Checked MSDN and there is a row count limit mentioned of 16,777,216。数据表没有列数限制。不能找到二维数组的限制。

我的问题不是为什么例外。我所寻找的是如果你正在做VSTO的开发,并有拍摄工作表中数据表来执行内存联接等等,你需要做到这一点:从

string[,] arr = new string[rc, cc]; 
Microsoft.Office.Interop.Excel.Range selection 
arr = selection.Value as string[,]; 

,然后复制数据该数组转换为数据表。现在什么是用户应该选择的元素数量的理想限制。所以我可以设置rowcount/columncount lmits并在选择超过这个标准时显示消息。

+0

我downvote感官表明您真的不应该指望什么不同,当您尝试分配的内存块的机器的整个地址空间的大小。 – Wug

+3

OP不应该对结果感到惊讶,但我不确定我是否同意所有的预测。这是一个公平的问题,简单的解释就足够了。 –

+1

也许吧。但这个问题似乎表明研究工作很差。这个例外确切地表明了什么是错误的,从数学的角度来看它是相当明显的,如果你将要分配20亿美元的东西,那最好是小得多。 – Wug

回答

16

让我们来做数学。您正尝试分配一个包含1048576 * 1638 = 1717567488元素的2D字符串数组。 x64上的字符串引用的大小为8个字节=>共1717567488 * 8 = 13740539904个字节。这是关于连续存储空间的大约13 GB。 CLR单个分配的最大大小为2GB,因此您将获得OutOfMemoryException,因为无法分配此单个块。

请注意,即使全部长度为1-2个字符,这样的字符串数量除了引用外还需要30GB的字符串值。除了OutOfMemoryException,你还期望得到什么?

+3

+1不知道空字符串是18字节 – Paparazzi

+2

是字符串通过参考存储?如果是的话,这只会分配大约6GB(仍然太大,但小于28GB) – Wug

+1

我同意Wug:string是一个引用类型,创建一个字符串数组用'null'初始化数组中的每个项目,而不是'string.Empty'。 –

0

Aleks, 您正在询问您的内存分配限制。 让我建议仅使用用户选择的细胞

  • 1.2通过使用xl.worksheet内只有确实使用的细胞改变你的观点和 限制你的输入要么

    • 1.1点

    除了你的问题,让我建议介意Range.ValueRange.Value2的区别:Range.Value包含用户输入eg如=SUM(A1:B10)的公式,而Range.Value2包含该公式的结果,例如10

    1.1只使用用户所选单元
    如前所述here使用Range userSelectedRange = Application.Selection;

    1.2您xl.worksheet
    使用Worksheet.Cells.SpecialCells属性中仅使用确实使用细胞。
    也许Worksheet.UsedRange更好。

    一个代码示例:

    int lastUsedRowIndex = xlWorksheet.Cells.SpecialCells(XlCellType.xlCellTypeLastCell).Row; 
    int lastUsedColIndex = xlWorksheet.Cells.SpecialCells(XlCellType.xlCellTypeLastCell).Column; 
    string rangeString = string.Format("A0:{0}{1}", SomeIndexToExcelColConverterFunc(lastUsedColIndex), lastUsedRowIndex)); 
    Xl.Range range = xlWorksheet.Range[rangeString]; 
    object[,] objectMatrix = range.Value2 as object[,]; 
    Marshal.ReleaseComObject(range);  
    // convert to string here if needed 
    
  • +0

    因为即使将'range.Value2'转换为'object [,]'',默认情况下该数组为空,所以我低估了这一点。如果在我的情况下,如果在一个Workbook中结束了154列,那么填充数组仍然会导致一个'System.OutOfMemoryException' – GrammatonCleric