简体   繁体   中英

ASP System.OutOfMemoryException only caught in Visual Studio not on production server

I have written a method to export the contents of an asp GridView object to Excel with formatting. On the very rare, but completely repeatable occasion where that particular GridView has a huge number of rows (24k) the method fails and gets caught and handled accordingly.

This works perfectly in Visual Studio (2015) but not when moved to the production server, which instead throws a System.OutOfMemoryException.

Method:

protected void ExportToExcel(object sender, EventArgs e)
{
    Button clickedButton = (Button)sender;
    GridView selectedGridview = GridView1;
    string filename = "FileNameHere";
    // Hidden unimportant selection of gridview
    if (selectedGridview.Rows.Count > 0)
    {
        try
        {
            Response.Clear();
            Response.Buffer = true;
            Response.AddHeader("content-disposition", "attachment;filename=" + filename + ".xls");
            Response.Charset = "";
            Response.ContentType = "application/vnd.ms-excel";
            using (StringWriter sw = new StringWriter())
            {
                HtmlTextWriter hw = new HtmlTextWriter(sw);

                //To Export all pages
                selectedGridview.AllowPaging = false;

                foreach (TableCell cell in selectedGridview.HeaderRow.Cells)
                {
                    cell.BackColor = selectedGridview.HeaderStyle.BackColor;
                }
                foreach (GridViewRow row in selectedGridview.Rows)
                {
                    foreach (TableCell cell in row.Cells)
                    {
                        if (row.RowIndex % 2 == 0)
                        {
                            cell.BackColor = selectedGridview.AlternatingRowStyle.BackColor;
                        }
                        else
                        {
                            cell.BackColor = selectedGridview.RowStyle.BackColor;
                        }
                        cell.CssClass = "textmode";
                        cell.Attributes.Add("style", "mso-number-format:\\@");
                    }
                }
                selectedGridview.RenderControl(hw);

                //style to format numbers to string
                string style = @"<style> .textmode {mso-number-format:\\@;} </style>";
                Response.Write(style);
                Response.Output.Write(sw.ToString());
            }
        }
        catch(System.OutOfMemoryException OOMex)
        {
            Response.Clear();
            // Another method gets called here to instead create a CSV file (much lighter on memory)
        }
        finally
        {
            Response.Flush();
            Response.End();
        }
    }

Any ideas as to why it works locally but throws the exception on production?

Any help would be greatly appreciated.

UPDATE:
I have since moved over to Mike Gledhill's library which drastically decreases complexity, but still raises the same error.

After discussing solutions with him, I had already set <httpRuntime maxRequestLength="1000000000" executionTimeout="7200"/> and proceeded to test by ignoring the session variables and directly exporting the DataTable to Excel. This works the same with the only difference being that now on the large result sets, I get System.IO.IsolatedStorage.IsolatedStorageException: Unable to create the store directory . I am consulting with the server manager at the moment to rectify this.

UPDATE 2:
I followed the following instructions to resolve the System.IO.IsolatedStorage.IsolatedStorageException : MSDN Forum
Everything is now working 100%!

Bottom Line:
I'd still like to know how or why an exception could get past my try/catch. Is it possible that the server won't run a catch clause if it is out of addressable/allocatable memory? Perhaps it "runs out" of memory in the catch clause and cannot get re-caught?

I can't exactly tell you why that exception is occurring, but if you're going to be writing particularly large Excel files, I would recommend doing it properly, using OpenXML , and the OpenXmlWriter library.

Here's a free C# library (with source code) which will take a DataSet , DataTable or List<> and create a real Excel .xlsx file.

Export to Excel class

Simply pass it whatever data source you used to populate your GridView , eg:

CreateExcelFile.CreateExcelDocument(myDataSet, "YourFilename.xlsx");

And if you're attempting to create the Excel file on a website, you just need to pass it the HttpResponse :

CreateExcelFile.CreateExcelDocument(myDataSet, "YourFilename.xlsx", Response);

But yes, you will need to modify this code, to add your Excel formatting.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM