Using report assemblies

By default, all reports before rendering should be compiled in an assembly. In the .NET framework application if the assembly is loaded in memory then it is locked in any case until the application domain will be unloaded.
In this case the assembly is saved in the windows temp directory and then is loaded in memory. Anyway loading of the report assembly as any other .NET assembly is a locked assembly file on the drive either in one or in other place and there is allocated memory.

There are several way to avoid this problem:

  1. Use reports in your application as C# classes (you can save them as classes from the report designer). In this case the report is being compiled with your application and accordingly it doesn't need to be compiled and loaded from assembly.

    Disadvantage of this way is that your project should be recompiled with new report class if you need to change the report template.

  2. Save reports as compiled assemblies in the Designer.

    Disadvantage of this way is that it is not useful to manage reports during the upgrade.

  3. Do not use report compilation. Instead of it you could use interpretation of the expressions in the report. You could enable this mode in the Calculation Mode report property.

    Disadvantage of this way is that not all expressions of the C# and VB.NET languages is interpreted. It's impossible to use events of components.

  4. Compilation and rendering a report in another application domain. In this case after rendering a report it is possible to load it into the assembly with this application domain. The locked file could be removed afterwards.
    The CreateReportInNewAppDomain() method of the StiReport class could be used to create a report and the UnloadReportAppDomain() method for uploading this report.

    Disadvantage of this way is that the RegData and RegBusinessObject methods are executed very slowly since the data marshalling to other domain is used. It is better request data in the report. Creating and uploading the application domain needs time.

  5. In our opition the most efficient way is compilation of a report when calling it first time. On every next calling the report is loaded from the compiled assembly. In this case only one copy of the report is stored in memory and there is only one assembly on the drive. The directory with the compiled report can be removed before using reports because they will be created again on first request. You can find a sample code below showing how this way works. A new report assembly is created, if it is not existed, if the report was changed, if the .NET Framework for what the assembly was compiled and the version under what the application is run are differed.

    Disadvantage of this way is that the first run is slow.

    StiReport report = new StiReport();
    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);
    	if (!Directory.Exists(folder)) Directory.CreateDirectory(folder);
  6. Precompilation of reports when updating them. This method is a modification of the previous one. After updating reports in the application or if they are not present, or, if necessary, the process of compiling of all reports start, which are used in the application. Before compilation the old version of assemblies is removed.

    Disadvantage of this way is that the compilation of reports could take some time.


Please sign in to leave a comment.