5

So recently I've been working on code in C#/ASP.NET that throws an error during selections of large parameters:

Exception of type 'System.OutOfMemoryException' was thrown. at System.Text.StringBuilder.ToString()

General Overview: Code queries a bunch of data from a database based on a selection by the user and puts in into an Excel document to be then be exported/downloaded by the user. It first uses StringBuilder to append the Prefix of the XML with:

const string startExcelXML = "<xml version>\r\n<Workbook " +
"xmlns=\"urn:schemas-microsoft-com:office:spreadsheet\"\r\n" +
" xmlns:o=\"urn:schemas-microsoft-com:office:office\"\r\n " +
"xmlns:x=\"urn:schemas-    microsoft-com:office:" +
"excel\"\r\n xmlns:ss=\"urn:schemas-microsoft-com:" +
"office:spreadsheet\">\r\n <Styles>\r\n " +
"<Style ss:ID=\"Default\" ss:Name=\"Normal\">\r\n " +
"<Alignment ss:Vertical=\"Bottom\"/>\r\n <Borders/>" +
"\r\n <Font/>\r\n <Interior/>\r\n <NumberFormat/>" +
"\r\n <Protection/>\r\n </Style>\r\n " +
"<Style ss:ID=\"BoldColumn\">\r\n <Font " +
"x:Family=\"Swiss\" ss:Bold=\"1\"/>\r\n </Style>\r\n " +
"<Style     ss:ID=\"StringLiteral\">\r\n <NumberFormat" +
" ss:Format=\"@\"/>\r\n </Style>\r\n <Style " +
"ss:ID=\"Decimal\">\r\n <NumberFormat " +
"ss:Format=\"0.0000\"/>\r\n </Style>\r\n " +
"<Style ss:ID=\"Integer\">\r\n <NumberFormat " +
"ss:Format=\"0\"/>\r\n </Style>\r\n <Style " +
"ss:ID=\"DateLiteral\">\r\n <NumberFormat " +
"ss:Format=\"mm/dd/yyyy;@\"/>\r\n </Style>\r\n " +
"</Styles>\r\n ";

It then goes through a loop that goes through and appends </Data></Cell> and the like as required before finally appending with:

const string endExcelXML = "</Workbook>";

After that it then return contentSB.ToString(); Since this is the only ToString() in the method the exception references, it has to be this piece of code.

Similar StackOverflow Issue: interesting OutOfMemoryException with StringBuilder

Thoughts: I've tried using the following code to get a general idea of how big the string is, which works for smaller selections, but doesn't output anything for larger selections and where contentSB is the StringBuilder object:

    System.Diagnostics.Debug.WriteLine("String:", contentSB);
    System.Diagnostics.Debug.WriteLine("String length:", contentSB.Length);

The referenced other StackOverflow issue occurs when appending, whereas mine is when returning a ToString(), so the cause of the issue might be different as it occurs not in the middle of Appending in the loop, but in the conversion process/return. What is the root cause and how do I fix it?

Community
  • 1
  • 1
Kurt Wagner
  • 3,295
  • 13
  • 44
  • 71

1 Answers1

1

Look like the string is bigger than what the memory can take. Guess that you could you be keeping long-lived references to large objects in memory?

Community
  • 1
  • 1
codingbiz
  • 26,179
  • 8
  • 59
  • 96
  • I put this issue on the backburner, but now I'm returning to it. If I were to implement the code such that after every X amount of loops (let's say an arbitruary 100) where the stringbuilder appends, it converts to string and appends what's in it to the 'meta' string, clears the stringbuilder, and then after it's done looping, returns the meta string, should that in theory, be more likely to work? – Kurt Wagner May 08 '13 at 18:52