2015-02-02 2 views
1

Я использую Visual Studio 2013 для создания рабочего стола WPF, у которого есть некоторые функции генерации отчетов, у меня около 30 отчетов, и пользователь может перейти от отчета к другому. Моя проблема в том, что каждый раз, когда я меняю ReportEmbeddedResource, а затем вызываю методы RefreshReport(), память увеличивается, поэтому, если пользователь просматривает все 30 отчетов, мое приложение будет потреблять около 130 Мб! Я знаю, что я должен выпустить Ресурсы после каждой навигации, я искал ее, но не нашел ответа; Вот мой кодКак избежать утечки памяти ReportViewer при навигации по многим отчетам?

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

Вы нашли ответ? – Julian50

+0

Nop Я этого не сделал, я помню, что однажды я прочитал, что у Microsoft есть эта ошибка в базе данных об ошибках, но в будущем она будет исправлена, поскольку в настоящее время это не их верхний приоритет! У меня нет ссылки на то, что я сказал. –

ответ

1

У меня нет большого опыта в этом, но кажется, что лучше всего использовать Safe Handles для получения отчетов внутри управляемой обертки, а затем использовать метод Dispose и заставить Collector Collector собирать , подавляя Finalizer. Обратите внимание, что использование памяти, которое вы видите в Taskmanager, является зарезервированной памятью, а не фактической памятью при текущем использовании; возможно, что вы освобождаете объект отчета, а taskmanager продолжает сообщать о высоких значениях памяти в исполняемом файле.

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

Весь метод может Уничтожение стать довольно запутанным так что не торопитесь и посмотрите здесь: MSDN - Implementing a Dispose Method MSDN - IDisposable.Dispose Method

0

У меня была такая же проблема с .NET 4.5 VS 2013

I попробовал несколько вещей, но что в итоге сделало его работу:

Компиляция проекта в x64 и использование LocalReport.ReleaseSandBoxAppDomain()

Я получил часть решения здесь: Very High Memory Usage in .NET 4.0

-2

Проблема решается комментарий MarkJ_KY по адресу https://connect.microsoft.com/VisualStudio/feedback/details/527451/ms-report-viewer-memory-leak-any-update-fix-winforms-application

Это может выглядеть немного сложным, но это не так. Идея состоит в том, чтобы создать AppDomain, сделать свой материал для отчетности в этом домене, а затем выгрузить домен. При разгрузке происходит освобождение всей памяти :-)

Я использовал это решение, которое решает проблему для меня.

+0

Не указывайте только ссылку в ответе. – Mistalis

Смежные вопросы