在另一个线程上渲染 ReportViewer
Posted
技术标签:
【中文标题】在另一个线程上渲染 ReportViewer【英文标题】:Rendering ReportViewer on another thread 【发布时间】:2014-08-21 12:05:21 【问题描述】:我正在尝试在 ASP .Net 中的另一个线程上呈现 ReportViewer:
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();
但我遇到了这个异常:
Microsoft.Reporting.WebForms.LocalProcessingException:本地报表处理过程中出错。 ---> Microsoft.ReportingServices.ReportProcessing.ReportProcessingException:无法加载表达式宿主程序集。详细信息:用于模拟的令牌无效 - 不能复制。 在 Microsoft.ReportingServices.RdlExpressions.ReportRuntime.ProcessLoadingExprHostException(ObjectType assemblyHolderObjectType,异常 e,ProcessingErrorCode 错误代码) 在 Microsoft.ReportingServices.RdlExpressions.ReportRuntime.LoadCompiledCode(IExpressionHostAssemblyHolder 表达式HostAssemblyHolder,布尔 includeParameters,布尔参数Only,ObjectModelImpl reportObjectModel,ReportRuntimeSetup runtimeSetup) 在 Microsoft.ReportingServices.OnDemandProcessing.Merge.Init (Boolean includeParameters, Boolean parametersOnly) 在 Microsoft.ReportingServices.OnDemandProcessing.Merge.Init(ParameterInfoCollection 参数) 在 Microsoft.ReportingServices.ReportProcessing.Execution.ProcessReportOdp.CreateReportInstance(OnDemandProcessingContext odpContext,OnDemandMetadata odpMetadata,ReportSnapshot 报告快照,合并和 odpMerge) 在 Microsoft.ReportingServices.ReportProcessing.Execution.ProcessReportOdp.Execute(OnDemandProcessingContext& odpContext) 在 Microsoft.ReportingServices.ReportProcessing.Execution.RenderReportOdpInitial.ProcessReport(ProcessingErrorContext errorContext、ExecutionLogContext executionLogContext、UserProfileState&userProfileState) 在 Microsoft.ReportingServices.ReportProcessing.Execution.RenderReport.Execute(IRenderingExtension newRenderer) 在 Microsoft.ReportingServices.ReportProcessing.ReportProcessing.RenderReport(IRenderingExtension newRenderer,DateTime executionTimeStamp,ProcessingContext pc,RenderingContext rc,IChunkFactory yukonCompiledDefinition) 在 Microsoft.Reporting.LocalService.CreateSnapshotAndRender(ReportProcessing repProc、IRenderingExtension 渲染器、ProcessingContext pc、RenderingContext rc、SubreportCallbackHandler subreportHandler、ParameterInfoCollection 参数、DatasourceCredentialsCollection 凭据) 在 Microsoft.Reporting.LocalService.Render(字符串格式,字符串 deviceInfo,字符串分页模式,布尔 allowInternalRenderers,IEnumerable 数据源,CreateAndRegisterStream createStreamCallback) 在 Microsoft.Reporting.WebForms.LocalReport.InternalRender(字符串格式,布尔 allowInternalRenderers,字符串 deviceInfo,PageCountMode pageCountMode,CreateAndRegisterStream createStreamCallback,警告 [] 和警告) --- 内部异常堆栈跟踪结束 --- 在 Microsoft.Reporting.WebForms.LocalReport.InternalRender(字符串格式,布尔 allowInternalRenderers,字符串 deviceInfo,PageCountMode pageCountMode,CreateAndRegisterStream createStreamCallback,警告 [] 和警告) 在 Microsoft.Reporting.WebForms.LocalReport.InternalRender(字符串格式,布尔 allowInternalRenderers,字符串 deviceInfo,PageCountMode pageCountMode,字符串和 mimeType,字符串和编码,字符串和文件名扩展,字符串 [] 和流,警告 [] 和警告) 在 Microsoft.Reporting.WebForms.LocalReport.Render(字符串格式、字符串 deviceInfo、PageCountMode pageCountMode、字符串和 mimeType、字符串和编码、字符串和文件名扩展、字符串 [] 和流、警告 [] 和警告) 在 Web.Controllers.ReportsController()谢谢,感谢任何帮助
【问题讨论】:
第一个问题(假设这仍然是一个问题):你能在同一个线程上成功运行它吗?) 嗨,它在同一个线程上成功运行。我反编译了 dll 并追踪到这条线被执行了windowsImpersonationContext = WindowsIdentity.Impersonate(IntPtr.Zero);
。谢谢
您是否在您的 web.config 中进行任何类型的模拟?您是否在报告中引用了任何其他程序集?
我没有做任何类型的模仿,但 AppPool 的身份是自定义的。在报告中没有其他程序集。它有表达式。
【参考方案1】:
我遇到了同样的问题,但使用的是 WPF 应用程序。
似乎 ReportViewer.RefreshReport 已经在另一个线程中运行了。
只需删除 async / Task,即使您在同一线程/时间刷新它们,它也可以正常工作。
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)
此代码添加了许多报告,所有报告同时开始刷新。
【讨论】:
报告应该在任务中生成,因为获取数据的阶段需要很长时间。在示例代码中不是简化代码的那个阶段。 @amit 这取决于您使用的报告类型:如果 RDL 数据由报告本身加载,如果您使用 RDLC,则可以在 任务上加载数据 然后将其传递给报表,但 RefreshReport 必须在主线程中调用(RefreshREport 自己在另一个线程上运行)。以上是关于在另一个线程上渲染 ReportViewer的主要内容,如果未能解决你的问题,请参考以下文章
Flask:在另一个页面上使用WTForm,而不是渲染表单本身