Xml 使用MVC的StringWriter出现内存不足异常,是否可以增加内存?

Xml 使用MVC的StringWriter出现内存不足异常,是否可以增加内存?,xml,asp.net-mvc,out-of-memory,Xml,Asp.net Mvc,Out Of Memory,我必须创建一个大型XML电子表格,现在它似乎已经达到了一次性处理的门槛 我不知道如何将其拆分,所以想知道是否有一种方法可以增加内存分配以用于内部目的 导致错误的代码如下所示: private string RenderViewToString() { using (var writer = new StringWriter()) { var view = ViewEngines.Engines.FindView(_context, _viewName, null)

我必须创建一个大型XML电子表格,现在它似乎已经达到了一次性处理的门槛

我不知道如何将其拆分,所以想知道是否有一种方法可以增加内存分配以用于内部目的

导致错误的代码如下所示:

private string RenderViewToString()
{
    using (var writer = new StringWriter())
    {
        var view = ViewEngines.Engines.FindView(_context, _viewName, null).View as RazorView;
        var viewDataDictionary = new ViewDataDictionary<TModel>(_model);
        var viewCtx = new ViewContext(_context, view, viewDataDictionary, new TempDataDictionary(), writer);
        viewCtx.View.Render(viewCtx, writer);
        return writer.ToString();
    }
}
是否有人找到了解决方法或知道如何将相关数据拆分为可管理的数据块,而无需全部重新编码

它从一个视图模型中获取数据,该模型本身在多个表中占用1到数万行数据,用户在单个Excel下载中需要这些数据,这会导致问题

字符串将输出到以下代码:

    protected override void WriteFile(HttpResponseBase response)
    {
        response.Write(RenderViewToString());

    }
但是,是否需要返回字符串的整个问题是无关紧要的,因为由于ViewContext.View.Render(ViewContext,TextWriter)崩溃,它永远不会走到那么远,所以有没有一种方法可以将ViewContext渲染到某个对象,而不会因为一个相对较小的文件(60+MB)而导致它崩溃

我曾尝试允许在web.config中使用大文件(一位同事建议),但没有成功

目前ViewContext太大,无法渲染,所以我只需要找到一种方法来渲染它,而不使用内置的,有什么想法吗

-----编辑-----

非常感谢Joe,我修改了您的代码,因为我没有将IIS设置为使用HttpContext头,但以下代码实现了这一点:

        HttpContext.Current.Response.Clear();
        using (var writer = new StreamWriter(HttpContext.Current.Response.OutputStream))
        {
            var view = ViewEngines.Engines.FindView(_context, _viewName, null).View
                as RazorView;
            var viewDataDictionary = new ViewDataDictionary<TModel>(_model);
            var viewCtx = new ViewContext(_context,
                view, viewDataDictionary, new TempDataDictionary(), writer);
            viewCtx.View.Render(viewCtx, writer);
        }
        return null;
HttpContext.Current.Response.Clear();
使用(var writer=newstreamwriter(HttpContext.Current.Response.OutputStream))
{
var view=ViewEngines.Engines.FindView(_context,_viewName,null).view
作为RazorView;
var viewDataDictionary=新的viewDataDictionary(_模型);
var viewCtx=新的ViewContext(_context,
视图、viewDataDictionary、新建TempDataDictionary()、编写器);
viewCtx.View.Render(viewCtx,writer);
}
返回null;

现在生成一个70MB的文件没有问题。

您正在将视图输出写入字符串,然后将其写入响应。您可能想做的是跳过中间人,将视图直接写入响应。由于
Render
方法接受任何
TextWriter
,因此您可以将
响应.OutputStream
传递给
StreamWriter
,而不只是写入普通字符串

比如:

System.Web.HttpContext.Current.Response.Clear();
System.Web.HttpContext.Current.Response.Headers[“内容处置”]=
“附件;文件名=somefile.txt”;//或者别的什么
System.Web.HttpContext.Current.Response.Headers[“内容类型”]=
“文本/普通”;//或者别的什么
使用(var writer=newstreamwriter(System.Web.HttpContext.Current.Response.OutputStream))
{
var view=ViewEngines.Engines.FindView(_context,_viewName,null).view
作为RazorView;
var viewDataDictionary=新的viewDataDictionary(_模型);
var viewCtx=新的ViewContext(_context,
视图、viewDataDictionary、新建TempDataDictionary()、编写器);
viewCtx.View.Render(viewCtx,writer);
}
返回null;

将视图输出写入字符串,然后将其写入响应。您可能想做的是跳过中间人,将视图直接写入响应。由于
Render
方法接受任何
TextWriter
,因此您可以将
响应.OutputStream
传递给
StreamWriter
,而不只是写入普通字符串

比如:

System.Web.HttpContext.Current.Response.Clear();
System.Web.HttpContext.Current.Response.Headers[“内容处置”]=
“附件;文件名=somefile.txt”;//或者别的什么
System.Web.HttpContext.Current.Response.Headers[“内容类型”]=
“文本/普通”;//或者别的什么
使用(var writer=newstreamwriter(System.Web.HttpContext.Current.Response.OutputStream))
{
var view=ViewEngines.Engines.FindView(_context,_viewName,null).view
作为RazorView;
var viewDataDictionary=新的viewDataDictionary(_模型);
var viewCtx=新的ViewContext(_context,
视图、viewDataDictionary、新建TempDataDictionary()、编写器);
viewCtx.View.Render(viewCtx,writer);
}
返回null;

是,安装更多RAM;)更多的RAM是没有帮助的(除非你能在64位的PC上安装1TB的内存:)。这里需要一种分页/拆分数据的策略。您真的需要字符串本身,还是正在写入某种输出,如文件或HTTP响应?@Joe-输出是一个Excel文件,允许用户保存或打开它。没别的了,结帐。它显示了如何返回纯文本文件,但您完全可以调整它以满足您的需要。是的,安装更多RAM;)更多的RAM是没有帮助的(除非你能在64位的PC上安装1TB的内存:)。这里需要一种分页/拆分数据的策略。您真的需要字符串本身,还是正在写入某种输出,如文件或HTTP响应?@Joe-输出是一个Excel文件,允许用户保存或打开它。没别的了,结帐。它展示了如何返回纯文本文件,但是你可以根据需要调整它。干杯,我会看一看并报告。现在它在工作一天后再次失败。。。还有其他想法吗?不是真的-这应该可以解决你在一个大字符串中遇到的问题。但是如果你有一个不同的大项目在内存中,像你的模型或字典,我不知道你是否可以轻松地修复它。解决这类问题通常意味着流式传输数据,而不是预先构建数据,但我不知道在这种数据类型下,您是否能够做到这一点。我可能会建议您尝试将数据拆分成更小的数据块,这样您一次就可以在内存中保留更少的数据。干杯,我会看一看,然后再报告。现在它在工作后再次失败
        HttpContext.Current.Response.Clear();
        using (var writer = new StreamWriter(HttpContext.Current.Response.OutputStream))
        {
            var view = ViewEngines.Engines.FindView(_context, _viewName, null).View
                as RazorView;
            var viewDataDictionary = new ViewDataDictionary<TModel>(_model);
            var viewCtx = new ViewContext(_context,
                view, viewDataDictionary, new TempDataDictionary(), writer);
            viewCtx.View.Render(viewCtx, writer);
        }
        return null;