这是我的问题..
我们的网站有两种类型的报告,网格中显示的数据和作为报告即时下载的数据。
这些报告可能包含几年的数据(超过100万行),我们一直允许客户在日期范围内下载数据,但我们已经开始限制他们可以查看数据的时间以防止出现性能问题我们的网站。然而,即使在较小的日期范围内,数据仍然变得非常大,现在它们正在扩展,如果它们下载太多,我们的内存会因为几次演出而耗尽内存。
我的问题是,我宁愿不限制他们的数据,所以我想找出一个很好的解决方案,允许他们尽可能多地下载。
我可以通过仅返回每页数据来限制他们看到的内容,因此没有性能问题,但下载始终是问题。
我已经研究过异步,但是还没有成功地将其工作,因为当我加载数据时它会激活内存。
想法?思考?建议?
代码示例:
// Get Data SqlConnection con = new SqlConnection(); SqlCommand cmd = new SqlCommand(); SqlDataAdapter da; DataSet ds = new DataSet(); con.ConnectionString = "MyConnectionString"; con.Open(); cmd.Connection = con; cmd.CommandType = CommandType.StoredProcedure; cmd.CommandText = "MyStoredProc"; da = new SqlDataAdapter(cmd); da.Fill(ds); con.Close(); StringWriter sw = new StringWriter(); HtmlTextWriter htw = new HtmlTextWriter(sw); DataGrid dg = new DataGrid(); dg.DataSource = ds.Tables[0]; dg.DataBind(); dg.RenderControl(htw); Response.ClearContent(); Response.ContentType = "application/vnd.ms-excel"; Response.AddHeader("Content-Disposition", "attachment;filename=Report.xls"); Response.Write(sw.ToString()); Response.End();
当我使用我的数据运行时...大约是800k行,我的内存出现峰值并且出现内存不足错误,并使事情变得更糟......它总是在RenderControl中占用直到完成
答案 0 :(得分:2)
我假设数据来自后端数据库。如果是这样,您不应让用户等待此操作完成。这是一个糟糕的UI设计,特别是当内存可以达到4GB时。
我同意其他建议,您应该考虑改进代码和设计,以帮助减少占用空间。但无论如何,你应该有类似预定的工作架构。
您允许用户在搜索/文件上下载,并将其添加到数据库表中的队列中。有一个db / .net进程,它会处理这些作业并在服务器上以适当的格式生成一个文件。如果数据相同并且您使用正确的命名约定,则可以在多个用户之间重用该文件。然后,用户应该能够进入下载队列页面并查看他已安排的所有下载。完成后,他将能够下载该文件。
如果您的要求不允许您这样做,请发表评论解释。
答案 1 :(得分:1)
好的,我们走了:
成品。
获取数据阅读器,随时编写HTML - 您永远不会将所有数据保存在内存中。你的方法永远不会扩展。
答案 2 :(得分:0)
您可以重写要分页的存储过程并循环遍历数据集吗?然后重写输出部分以流式传输文件而不是一次性输出它(您当前的方法基本上只是写出一个HTML表格)。
分页数据将使下载过程不会将所有数据存储在内存中
答案 3 :(得分:0)
解决了!!!
当我在Excel中导出大量数据时,我面临同样的问题。
解决方案:您可以使用open XMl dll来解决您的问题。 使用这个dll你可以在excel中导出大量数据,内存消耗也会更少。
您可以从这里获得更多信息 https://msdn.microsoft.com/en-us/library/office/hh180830(v=office.14).aspx