1
votes

I'm trying to render ReportViewer on another thread in ASP .Net:

    public ActionResult GenerateReport()
    {
    var task = Task.Factory.StartNew(() =>
    {
        try
        {
            using (LocalReport localReport = new LocalReport())
            {
                System.Reflection.Assembly assembly = System.Reflection.Assembly.LoadFrom(AppDomain.CurrentDomain.BaseDirectory + "bin\\" + "Reports.dll");
                using (System.IO.Stream stream = assembly.GetManifestResourceStream("Report.rdlc"))
                {


                    localReport.LoadReportDefinition(stream);
                    string mimeType;
                    string encoding;
                    string fileNameExtension;

                    Warning[] warnings;
                    string[] streams;
                    byte[] rendered;

                    //Render the report
                    renderedBytes = localReport.Render(
                        "PDF",
                        deviceInfo,
                        out mimeType,
                        out encoding,
                        out fileNameExtension,
                        out streams,
                        out warnings);

                   Session["Report"] = renderedBytes;
                }
            }
        }
        catch (Exception ex)
        {
            Logger.Error("Error", ex);
        }
    });

    return new View();
 }

But I'm geeting this exception:

Microsoft.Reporting.WebForms.LocalProcessingException: An error occurred during local report processing. ---> Microsoft.ReportingServices.ReportProcessing.ReportProcessingException: Failed to load expression host assembly. Details: Invalid token for impersonation - it cannot be duplicated.
   at Microsoft.ReportingServices.RdlExpressions.ReportRuntime.ProcessLoadingExprHostException(ObjectType assemblyHolderObjectType, Exception e, ProcessingErrorCode errorCode)
   at Microsoft.ReportingServices.RdlExpressions.ReportRuntime.LoadCompiledCode(IExpressionHostAssemblyHolder expressionHostAssemblyHolder, Boolean includeParameters, Boolean parametersOnly, ObjectModelImpl reportObjectModel, ReportRuntimeSetup runtimeSetup)
   at Microsoft.ReportingServices.OnDemandProcessing.Merge.Init(Boolean includeParameters, Boolean parametersOnly)
   at Microsoft.ReportingServices.OnDemandProcessing.Merge.Init(ParameterInfoCollection parameters)
   at Microsoft.ReportingServices.ReportProcessing.Execution.ProcessReportOdp.CreateReportInstance(OnDemandProcessingContext odpContext, OnDemandMetadata odpMetadata, ReportSnapshot reportSnapshot, Merge& odpMerge)
   at Microsoft.ReportingServices.ReportProcessing.Execution.ProcessReportOdp.Execute(OnDemandProcessingContext& odpContext)
   at Microsoft.ReportingServices.ReportProcessing.Execution.RenderReportOdpInitial.ProcessReport(ProcessingErrorContext errorContext, ExecutionLogContext executionLogContext, UserProfileState& userProfileState)
   at Microsoft.ReportingServices.ReportProcessing.Execution.RenderReport.Execute(IRenderingExtension newRenderer)
   at Microsoft.ReportingServices.ReportProcessing.ReportProcessing.RenderReport(IRenderingExtension newRenderer, DateTime executionTimeStamp, ProcessingContext pc, RenderingContext rc, IChunkFactory yukonCompiledDefinition)
   at Microsoft.Reporting.LocalService.CreateSnapshotAndRender(ReportProcessing repProc, IRenderingExtension renderer, ProcessingContext pc, RenderingContext rc, SubreportCallbackHandler subreportHandler, ParameterInfoCollection parameters, DatasourceCredentialsCollection credentials)
   at Microsoft.Reporting.LocalService.Render(String format, String deviceInfo, String paginationMode, Boolean allowInternalRenderers, IEnumerable dataSources, CreateAndRegisterStream createStreamCallback)
   at Microsoft.Reporting.WebForms.LocalReport.InternalRender(String format, Boolean allowInternalRenderers, String deviceInfo, PageCountMode pageCountMode, CreateAndRegisterStream createStreamCallback, Warning[]& warnings)
   --- End of inner exception stack trace ---
   at Microsoft.Reporting.WebForms.LocalReport.InternalRender(String format, Boolean allowInternalRenderers, String deviceInfo, PageCountMode pageCountMode, CreateAndRegisterStream createStreamCallback, Warning[]& warnings)
   at Microsoft.Reporting.WebForms.LocalReport.InternalRender(String format, Boolean allowInternalRenderers, String deviceInfo, PageCountMode pageCountMode, String& mimeType, String& encoding, String& fileNameExtension, String[]& streams, Warning[]& warnings)
   at Microsoft.Reporting.WebForms.LocalReport.Render(String format, String deviceInfo, PageCountMode pageCountMode, String& mimeType, String& encoding, String& fileNameExtension, String[]& streams, Warning[]& warnings)
   at Web.Controllers.ReportsController()

Thanks, and appreciate any help

1
First question (assuming this is still a problem): can you run it successfully on the same thread?)Ann L.
Hi, on the same thread it runs succesfully. I decompile the dll and trace that this line is executed windowsImpersonationContext = WindowsIdentity.Impersonate(IntPtr.Zero);. Thanksamit
Are you doing any kind of impersonation in your web.config? Are you referencing any additional assemblies in your report?Ann L.
I'm not doing any kind of impersonation, but the identity of the AppPool is custom. In the report there arn't additional assemblies. It has expressions.amit

1 Answers

0
votes

I was experiencig the same problem but with WPF App.

It seems that ReportViewer.RefreshReport Allready runs in another thread.

Just remove the async / Task and It Works fine even if you refresh some them at the same thread / time.

            foreach (ReportViewer r in ListaReportes)
            {
                ContentPresenter Presenter = new ContentPresenter();
                Presenter.Width = 200;
                Presenter.Height = 260;
                WindowsFormsHost Host = new WindowsFormsHost();
                Host.Child = r;
                Presenter.Content = Host;
                Miniaturas.Children.Add(Presenter);

                try
                {
                    r.RefreshReport();
                } catch(Exception)
                {
                }
            } 

This code add many reports and all of them starts refreshing at the same time.