2012-10-10 36 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