ASP System.OutOfMemoryException 只在 Visual Studio 不在生产服务器上

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

我编写了一种方法,可以将 asp GridView 对象的内容导出到 Excel 并设置格式。 在非常罕见但完全可重复的情况下,特定的 GridView 具有大量行 (24k),该方法失败并被捕获并进行相应处理。

这在 Visual Studio (2015) 中完美运行,但在移动到生产服务器时却不行,而是抛出 System.OutOfMemoryException.

方法:

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();
        }
    }

关于为什么它在本地工作但在生产中抛出异常的任何想法?

如有任何帮助,我们将不胜感激。

更新:
我已经转移到 Mike Gledhill 的库,它大大降低了复杂性,但仍然会引发同样的错误。

和他商量解决方案后,我已经设置好<httpRuntime maxRequestLength="1000000000" executionTimeout="7200"/>,直接忽略session变量直接导出DataTable到Excel进行测试。 这与现在在大型结果集上的唯一区别相同,我得到 System.IO.IsolatedStorage.IsolatedStorageException: Unable to create the store directory。我正在咨询服务器管理员以纠正此问题。

更新 2:
我按照以下说明解决了 System.IO.IsolatedStorage.IsolatedStorageExceptionMSDN Forum
现在一切正常 100%!

底线:
我仍然想知道异常如何或为什么可以通过我的 try/catch。 如果 addressable/allocatable 内存不足,服务器是否可能不会 运行 catch 子句?也许它 "runs out" 的内存在 catch 子句中并且无法被重新捕获?

我无法确切地告诉您为什么会出现该异常,但是如果您要编写特别大的 Excel 文件,我建议您正确地使用 OpenXML,和 OpenXmlWriter 图书馆。

这是一个免费的 C# 库(带有源代码),它将采用 DataSetDataTableList<> 并创建一个真正的 Excel .xlsx 文件。

Export to Excel class

只需将您用来填充 GridView 的任何数据源传递给它即可,例如:

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

如果您试图在网站上创建 Excel 文件,您只需将其传递给 HttpResponse:

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

但是,是的,您需要修改此代码,以添加您的 Excel 格式。