Lie*_*oen 2 .net asp.net response.write out-of-memory
将大量数据导出到字符串(csv格式)时,我得到一个OutOfMemoryException.解决这个问题的最佳方法是什么?该字符串将返回到Flex应用程序.
我要做的是将csv导出到服务器磁盘并返回给Flex的URL.像这样,我可以刷新写入磁盘的流.
更新:
String是使用StringBuilder构建的:
StringBuilder stringbuilder = new StringBuilder();
string delimiter = ";";
bool showUserData = true;
// Get the data from the sessionwarehouse
List<DwhSessionDto> collection
=_dwhSessionRepository.GetByTreeStructureId(treeStructureId);
// ADD THE HEADERS
stringbuilder.Append("UserId" + delimiter);
if (showUserData)
{
stringbuilder.Append("FirstName" + delimiter);
stringbuilder.Append("LastName" + delimiter);
}
stringbuilder.Append("SessionId" + delimiter);
stringbuilder.Append("TreeStructureId" + delimiter);
stringbuilder.Append("Name" + delimiter);
stringbuilder.Append("Score" + delimiter);
stringbuilder.Append("MaximumScore" + delimiter);
stringbuilder.Append("MinimumScore" + delimiter);
stringbuilder.Append("ReducedScore" + delimiter);
stringbuilder.Append("ReducedMaximumScore" + delimiter);
stringbuilder.Append("Duration" + delimiter);
stringbuilder.AppendLine("Category" + delimiter);
foreach (var dwhSessionDto in collection)
{
stringbuilder.Append(
getPackageItemsInCsvFromDwhSessionDto(
dwhSessionDto, delimiter, showUserData));
}
return stringbuilder.ToString();
Run Code Online (Sandbox Code Playgroud)
该字符串将发送回Flex,如下所示:
var contentType = "text/csv";
string result = exportSessionService.ExportPackage(treeStructureId);
// Write the export to the response
_context.Response.ContentType = contentType;
_context.Response.AddHeader("content-disposition",
String.Format("attachment; filename={0}", treeStructureId + ".csv"));
// do not Omit the Vary star so the caching at the client side will be disabled
_context.Response.Cache.SetOmitVaryStar(false);
_context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
if (!String.IsNullOrEmpty(result))
{
_context.Response.Output.Write(result);
_context.Response.Output.Close();
}
else
{
_context.Response.Output.Write("No logs");
}
Run Code Online (Sandbox Code Playgroud)
您的CSV字符串增长到超过80000字节,最后是LargeObjectHeap.LOH不是以与其他代相同的方式进行垃圾收集,并且可能会随着时间的推移而碎片化,例如在向服务器发出许多请求之后,或者如果使用字符串连接(淘气!)来构建此csv数据.结果是您的程序保留了比实际使用的内存更多的内存,并抛出了OutOfMemory异常.
此实例中的修复是将csv数据直接写入Response流而不是字符串变量甚至StringBuilder.这不仅可以避免大对象堆,而且可以降低整体内存使用率并开始更快地将数据推送给用户.
我要做的是将csv导出到服务器磁盘
听起来像是正确的想法.但是你先创建完整的字符串吗?如果你逐行写,你不应该得到OOM
您只是使用StringBuilder.Append(x),因此您可以稍微重新构建代码以替换它_context.Response.Output.Write(x).这可能会牺牲你的一点点分离,但这是一个很好的理由.
如果你想继续使用StringBuilder,如果你能估算出最终的大小,它会有很大的帮助.添加大量保证金并使用
StringBuilder stringbuilder = new StringBuilder(estimate);
Run Code Online (Sandbox Code Playgroud)
这节省了StringBuilder的增长(复制)并减少了LOH上的内存使用和碎片.
String使用StringBuilder创建,并通过HttpContext.Reponse.Output.Write(result)传回Flex应用程序; - Lieven Cardoen
所以你基本上做的是:
StringBuilder str = new StringBuilder();
while(whatever)
{
str.Append(thisNextLineIGuess);
}
Response.Output.Write(str.ToString());
Run Code Online (Sandbox Code Playgroud)
正确?这可能不是您的确切代码,但听起来像是一个很好的近似值.
然后解决方案很简单:
while(whatever)
{
Response.Output.Write(thisNextLineIGuess);
}
Run Code Online (Sandbox Code Playgroud)
流式传输通常比缓冲整个事物并将其作为一个整体发送出去更好.
| 归档时间: |
|
| 查看次数: |
4803 次 |
| 最近记录: |