3

我在使用 ReportViewer 时遇到了一些问题。基本上代码如下:

public void Display(object dataSource, ReportViewer viewer)
    {
        currentDs = dataSource as MyTypes;

        if (currentDs != null)
        {
            var param = new LinkedList<ReportParameter>();
            param.AddFirst(new ReportParameter("Title", "Title"));
            viewer.ProcessingMode = ProcessingMode.Local;
            viewer.LocalReport.ReportEmbeddedResource = ReportName;
            viewer.LocalReport.EnableExternalImages = true;
            viewer.LocalReport.DataSources.Add(new ReportDataSource(DataSourceName + "_Header", currentDs.Header));
            viewer.LocalReport.DataSources.Add(new ReportDataSource(DataSourceName + "_Footer", currentDs.Footer));
            viewer.LocalReport.DataSources.Add(new ReportDataSource(DataSourceName + "_Lines", currentDs.Lines));

            viewer.LocalReport.SetParameters(param);
            viewer.RefreshReport();
        }
    }

问题是有时它会生成 rdlc 报告,但有时它只是挂起应用程序。具体来说,它停留在 viewer.RefreshReport(); 永远。

在 rdlc 文件上正确设置了相应的参数和数据集。

有没有人经历过类似的行为?

提前致谢。

4

4 回答 4

3

我想您的查看器配置正确。

第一代通常会成功吗?您可以尝试viewer.Reset()在每次生成报告后调用,这可能会解决一些复杂的问题。

于 2013-03-22T16:18:18.853 回答
3

一篇 2006 年的帖子表面上看起来很相关,可能会给你一个解决方法,尽管我不得不承认我自己没有这样做,因为我几乎不可能重现你看到的问题和所以同样不可能看到是否有任何解决方法可以解决它。这并不理想,但我希望没有无用信息之类的东西:-)

相关信息位于链接线程的底部,为了清楚起见,我在下面引用了它。

ReportViewer 控件分为两个组件 - 报表对象(公开为 .ServerReport 和 .LocalReport)和 UI(实际的 ReportViewer 类)。报告对象存储有关您的报告的所有状态。UI 组件只是调用它们来获取显示报告、参数提示、工具栏等所需的信息。

UI 组件不是线程安全的,就像大多数控件一样。但是报表对象是线程安全的。当您调用 RefreshReport 时,查看器使用后台线程对报表对象调用 Render。但这不是控件调用报表对象的唯一一次。第一次需要编译报表定义(本地报表)或创建会话(服务器报表)可能需要很长时间。如果这个“第一次”是在 RefreshReport 期间,它将发生在后台线程上。但正如您所见,它可能发生在其他时间。例如,填充参数 UI 需要调用 GetParameters,这也需要此启动惩罚。

如果你想保证这个“第一次”惩罚是在后台线程上,那么在设置报告路径和其他连接/数据源信息之后,从后台线程调用 GetParameters。

这似乎建议您ReportViewer从后台线程而不是从 UI 线程对您的 always 进行一些调用,以便任何延迟都不会影响 UI。对我来说,这听起来有点像一个笨拙的设计!

这对你有帮助吗?

于 2013-03-27T07:40:43.780 回答
1

我可能已经修好了。这个页面帮助我弄清楚:http: //ikriv.com/dev/dotnet/MysteriousHang.html

因此,似乎 a) 需要在 UI 线程上创建报告查看器,并且 b) 这并不总是可靠地发生(有关详细信息,请参阅链接)。报表查看器是 .NET 2 组件,链接中记录的行为适用于 .NET 2。

为了解决这个问题,我采用了以下技巧:

  • 第一个技巧:在启动时命名 UI 线程
  • 第二个技巧:尽早强制处理,然后获取对同步上下文的引用
  • 第三个技巧:使用线程名称和同步上下文来实现所需的调用 -> 调用惯用语。

如果这一切都在一起,我会回来发布更多细节。

于 2013-04-18T23:28:05.940 回答
0

我在带有 .Net 4.0 和 Report Viewer 2010 的 Windows XP 中遇到了这个问题。是的,操作系统已终止支持,但 Windows Embedded POSReady 2009 (Windows XP SP3),它仍处于扩展支持状态,直到 2019 年 4 月。

要解决挂起问题,请调用已弃用的 API 来呈现报告

rptviewer.LocalReport.ExecuteReportInSandboxAppDomain();

并且当退出或重新运行报告时,例如报告的参数发生变化,报告需要通过正确清理

rptviewer.LocalReport.DataSources.Clear();
rptviewer.LocalReport.ReportEmbeddedResource = null;
rptviewer.LocalReport.Dispose();
// release sandbox is required to prevent the lock up, see below note on display report
rptviewer.LocalReport.ReleaseSandboxAppDomain();

// clean up report viewer
rptviewer.Clear();
rptviewer.Reset();

注意在 Windows 7、8、8.1 和 10 上。不会发生挂起问题。

于 2017-05-19T05:27:23.707 回答