Возможности создания метода, компилирующего в оперативную память и возвращающего сборку, не существует из-за ограничений .Net Framework. Если в приложении .Net загружается сборка, то эта сборка блокируется до момента закрытия приложения. Даже если сборка загружается из потока. В этом случае, сборка сохраняется в temp директорию windows, а потом грузится в память. Загрузка сборки отчета (как и любой другой сборки .Net) это заблокированный файл сборки на диске в том или ином месте, и занятая для нее память.

 

Есть некоторые варианты обхода данной проблемы:

 

strel11 Использовать отчеты в приложении в виде С# классов (сохраняя их в виде классов из дизайнера отчетов). В этом случае, отчет компилируется вместе с Вашим приложением, и соответственно ему не требуется компиляция и загрузка сборки. При обновлении, неудобно администрировать отчеты.

 

strel11 Использовать отчеты в виде скомпилированной сборки, т.е. сохранять отчеты в виде сборок из дизайнера отчетов. В этом случае, также неудобно администрировать отчеты при обновлении.

 

strel11 Не использовать компиляцию отчетов. Вместо нее использовать интерпретацию выражений в отчете. Режим интерпретации можно включить при помощи свойства отчета CalculationMode. Однако, стоит учитывать, что интерпретатор выражений работает медленнее, чем скомпилированные выражения. И не все выражения языка С# и VB.Net интерпретатор может интерпретировать. Кроме того, нельзя использовать события у компонентов отчета.

 

strel11 Компиляция и построение отчета в другом домене приложения. В этом случае, после построения отчета можно выгрузить его сборку вместе со всем доменом приложения из памяти. Заблокированный файл сборки можно после выгрузки удалить. Для создания отчета можно использовать метод CreateReportInNewAppDomain() класса StiReport. Для его выгрузки - UnloadReportAppDomain(). Однако в этом случае, метод RegData и RegBusinessObject работают очень медленно (т.к. используется маршалинг данных в другом домене). Данные лучше всего запрашивать из самого отчета. Создание и удаление домена приложения занимает определенное время.

 

strel11 Один из самых эффективных способов - это компиляция отчета при первом обращении к отчету. А при каждом последующем обращении - загрузка отчета из ранее скомпилированной сборки. В данном случае, отчет хранится в памяти только один раз, сборка на диске только один раз. Перед запуском приложения папку, где хранятся отчеты можно удалять (до использования отчетов), т.к. все отчеты будут созданы заново (при обращении к ним). Ниже приводится код, который использует данный способ. Новая сборка отчета создается если ее нет, или если отчет был изменен, а также в случае, если версия .NET Framework, для которой была собрана сборка, и версия под которой запущено приложение не совпадают. При этом способе только первый запуск медленный.

 

Sample

...
StiReport report = new StiReport();

report.Load(file);

 

string folder = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);

folder = Path.Combine(folder, "Stimulsoft\\CompiledReports");

folder = Path.Combine(folder, System.Runtime.InteropServices.RuntimeEnvironment.GetSystemVersion().ToString());

string compiledReportFile = Path.Combine(folder, report.GetReportAssemblyCacheName());

 

if (File.Exists(compiledReportFile))

{

report = StiReport.GetReportFromAssembly(compiledReportFile, true);

}

else

{

if (!Directory.Exists(folder)) Directory.CreateDirectory(folder);

report.Compile(compiledReportFile);

}

report.Render(false);
...

 

 

strel11 Прекомпиляция отчетов при их обновлении. Данный способ является вариацией предыдущего. После обновления отчетов в приложении, или если их нет вообще, или если это необходимо, запускается процесс компиляции всех отчетов, которые используются в приложении. Перед компиляцией старая версия сборок удаляется. Иногда процесс компиляции отчетов, при данном способе, может занять некоторое время.