MVC Razor查看' System.OutOfMemoryException'具有大值字符串

时间:2017-02-08 05:29:09

标签: c# json asp.net-mvc razor

我有一个很大的JSON对象,我需要传递给Web浏览器中显示的视图。由于我不能让一个带有Action的Controller返回这个JSON对象,我想在Razor视图中添加JSON对象。

  1. @Html.Hidden("fileContent", fileContent);

  2. <textarea style="display:none"> @fileContent </textarea>

  3. 上述所有内容都不如我所期望的那样,并且给了我,

      

    类型的异常&#39; System.OutOfMemoryException&#39;被扔了。

         

    描述:执行当前Web请求期间发生了未处理的异常。请查看堆栈跟踪以获取有关错误及其源自代码的位置的更多信息。

         

    异常详细信息:System.OutOfMemoryException:类型的异常&#39; System.OutOfMemoryException&#39;被扔了。

    是的,我同意以另一种方式(may be as Mediator suggest重组流程或者有一个返回JSON对象的操作更好。)

    1. 这是MVC的限制,我们可以为MVC视图设置最大尺寸吗?
    2. 这是因为IIS Express配置吗?
    3. 还有其他方法可以解决这个问题吗?或者将大对象传递给客户端浏览器的最佳方法。
    4. 感谢您的时间。任何帮助都将受到高度赞赏。

      修改

      控制器

      var file = System.IO.File.ReadAllText(HttpContext.Server.MapPath("~/content/data.csv"));
      ViewData.Add("file", file);
      return View();
      

      堆栈跟踪

        

      [OutOfMemoryException:类型的异常&#39; System.OutOfMemoryException&#39;   被抛出。] System.Text.StringBuilder.ExpandByABlock(Int32   minBlockCharCount)+163 System.Text.StringBuilder.Append(Char *   value,Int32 valueCount)+82
        System.Text.StringBuilder.AppendHelper(String value)+31
        System.Text.StringBuilder.Append(String value)+186
        System.IO.StringWriter.Write(String value)+30
        System.Web.WebPages.WebPageBase.Write(Object value)+87

1 个答案:

答案 0 :(得分:-1)

根据您的CSV文件大小,最好使用ReadLines而不是ReadAllText,如下所示:

var sb = new StringBuilder();
sb.Capacity = 16; // default, adjust it to less number as you wish

foreach (String line in System.IO.File.ReadLines(HttpContext.Server.MapPath("~/content/data.csv")))
{
    sb.Append(line);    
}

ViewData.Add("file", sb.ToString());

ReadLines返回IEnumerable<String>逐行读取文件(一次一行),因此它适用于某些文件,这些文件在存储为单个大字符串时可能会占用大量内存空间。 / p>

但是,如果文件内容非常大,请考虑使用StreamReader而不是StringBuilder,这需要连续的数组大小并取决于heap fragmentation

using (var sr = new System.IO.StreamReader(HttpContext.Server.MapPath("~/content/data.csv")))
{
     String line;
     while ((line = sr.ReadLine()) != null)
     {
         // combine source strings here
     }
}

请注意,每个字符需要2个字节,字符串是字符数组,因此应该有连续的数组,这些数组会在内存中生成对象时影响性能和大小。因此,在处理需要立即清理的大量对象后,使用GC.Collect()方法优化垃圾收集器功能可能会有所帮助。

相关参考资料:

interesting OutOfMemoryException with StringBuilder

MSDN: System.Text.StringBuilder

MSDN: System.IO.StreamReader

Eric Lippert: Out Of Memory” Does Not Refer to Physical Memory