我正在使用Visual Studio 2013来创建具有一些报告生成功能的WPF桌面应用程序,我有大约30个报告,用户可以从报告切换到另一个报告。我的问题是,每次我更改ReportEmbeddedResource
然后调用RefreshReport()
方法时,内存都会增加,因此如果用户浏览所有30个报告,我的应用程序将消耗大约130 Mb!我知道我必须在每次导航后发布资源,我用Google搜索,但没有找到答案;这是我的代码
public MainWindow() // constructor
{
InitializeComponent();
this.reportViewer.ZoomMode = Microsoft.Reporting.WinForms.ZoomMode.PageWidth;
InitDataSources();
}
private void InitDataSources()
{
//manager data source
mangerDataSource = new ReportDataSource();
mangerDataSource.Name = "ManagerDataSet";
mangerDataSource.Value = uow.Members.GetAll().
ToList().Where((s) => s.MemberType == MemmberTypes.Manager);
reportViewer.LocalReport.DataSources.Add(mangerDataSource);
//adding 2 other data sources
}
public void RenderReport(string reportKey)
{
reportViewer.Reset();
string path = "Manager";
if (reportKey.Contains("tea")) path = "Teacher";
if (reportKey.Contains("stu")) path = "Student";
reportViewer.LocalReport.ReportEmbeddedResource = string.Format(
"Printers.Reports.{0}.{1}.rdlc", path,reportKey);
reportViewer.RefreshReport();
}
有没有办法在渲染新报告后发布旧的报告资源?
答案 0 :(得分:1)
我对此没有多少经验,但似乎您可以做的最好的事情是使用安全句柄将报告放在一个可管理的包装器中,然后使用Dispose方法并强制垃圾收集器收集,同时压制终结器。请注意,您在Taskmanager中看到的内存使用量是保留内存,而不是当前使用的实际内存;您可能会释放报表对象,并且任务管理器会继续报告可执行文件的高内存值。
reportViewer.Dispose();
GC.SuppressFinalize(reportViewer);
整个处理方法可能会变得非常混乱,所以请花点时间看看这里: MSDN - Implementing a Dispose Method MSDN - IDisposable.Dispose Method
答案 1 :(得分:0)
我遇到了与.NET 4.5 VS 2013相同的问题
我尝试了几件事,但最终使它发挥作用的是:
在x64中编译项目并使用LocalReport.ReleaseSandBoxAppDomain()
我从这里得到了部分解决方案:Very High Memory Usage in .NET 4.0
答案 2 :(得分:-2)
看起来有点复杂,但事实并非如此。我们的想法是创建一个AppDomain,在该域中执行报告,然后卸载域。当卸载所有内存时: - )
我已经使用了解决问题的解决方案。