2

I am using Visual Studio 2013 to create a WPF Desktop application that have some report generation functionalities, I have about 30 report and the user can swich from a report to another. My problem is that each time I change ReportEmbeddedResource and then call the RefreshReport() methods, the memory increases, so if the user navigate through all the 30 report my app will consume about 130 Mb! I know that I have to release the Resources after each navigation, I googled about that but didn't find an answer; Here is my code

 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();

    }

Is there a way to release the old report resource after Rendering a new report?

Benzara Tahar
  • 2,058
  • 1
  • 17
  • 21
  • did you find an answer ? – Julian50 Apr 13 '15 at 09:52
  • Nop I didn't, I remember that i read once that Microsoft has that bug on their bugs database but it is planned to be fixed in the future as it is not their top prioroty currently! I don't have the link for what i said. – Benzara Tahar Apr 14 '15 at 10:02

3 Answers3

1

I don't have much experience with this but it seems that the best thing you can do is to use the Safe Handles to get your reports inside a manageable wrapper and then use the Dispose method and force the Garbage Collector to collect, while suppressing the Finalizer. Note that the memory usage you see in the Taskmanager is reserved memory, not actually memory in current use; it is possible that you release the report object and the taskmanager continues to report high memory values on the executable.

reportViewer.Dispose();
GC.SuppressFinalize(reportViewer);

The whole Disposing Method can become quite confusing so take your time and have a look here: MSDN - Implementing a Dispose Method MSDN - IDisposable.Dispose Method

Ricardo Giro
  • 134
  • 3
0

I was having the same issue with .NET 4.5 VS 2013

I tried several things, but what finally made it work was:

Compiling the project in x64 and using LocalReport.ReleaseSandBoxAppDomain()

I got part of the solution from here: Very High Memory Usage in .NET 4.0

Community
  • 1
  • 1
-3

Problem is solved by MarkJ_KY's comment at https://connect.microsoft.com/VisualStudio/feedback/details/527451/ms-report-viewer-memory-leak-any-update-fix-winforms-application

It might look a little complex but it is not. The idea is to create an AppDomain, do your reporting stuff in that domain and then unload the domain. When unloading all memory are released :-)

I have used that solution which solves the problem for me.

Ken
  • 11
  • 2