当将大量数据导出到字符串(csv 格式)时,出现 OutOfMemoryException。解决这个问题的最佳方法是什么?该字符串返回到 Flex 应用程序。

我要做的是将 csv 导出到服务器磁盘并将 url 返回给 Flex。像这样,我可以刷新写入磁盘的流。

更新:

字符串是用 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(); 

字符串像这样发送回 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"); 
} 

请您参考如下方法:

您的 CSV 字符串正在增长到超过 80000 字节并最终出现在 LargeObjectHeap 上。 LOH 不会像其他代那样以相同的方式进行垃圾收集,并且会随着时间的推移而碎片化,例如在对您的服务器发出许多请求之后,或者如果您使用字符串连接(调皮!)来构建此 csv 数据。结果是您的程序保留的内存比它实际使用的多得多,并抛出 OutOfMemory 异常。

此实例中的解决方法是将您的 csv 数据直接写入响应流,而不是字符串变量甚至 StringBuilder。这不仅可以避免大对象堆,而且可以降低整体内存使用率,并开始更快地将数据推送给用户。


评论关闭
IT序号网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!