【问题标题】:WinForms ReportViewer hangs the app WPFWinForms ReportViewer 挂起应用程序 WPF
【发布时间】:2013-03-04 07:16:43
【问题描述】:

我在使用 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文件上正确设置了相应的参数和数据集。

有没有人遇到过类似的行为?

提前致谢。

【问题讨论】:

  • 使用相同参数时是否随机出现?
  • 是的。有时挂起,而另一些则不使用相同的数据集。
  • 我知道你的数据集是否包含相同的值?
  • 您是否尝试过在其中一个挂起期间附加调试器并暂停执行?如果是这样,您可以为运行此调用的线程添加调用堆栈吗?
  • @WiiMaxx,我正在与 Maxi 合作,它似乎是数据不变的:针对未更改的静态数据运行具有相同参数的相同报告,有时应用程序会挂起,有时不会。一切都指向某种难以捉摸的线程问题,可能与 WPF 有关。我们以前从未在直接的 winforms 应用程序中看到过这种情况。

标签: wpf report reporting reportviewer rdlc


【解决方案1】:

我想你的观众 configured 是正确的。

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

【讨论】:

    【解决方案2】:

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

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

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

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

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

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

    这对你有帮助吗?

    【讨论】:

      【解决方案3】:

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

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

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

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

      如果一切顺利,我会回来发布更多详细信息。

      【讨论】:

        【解决方案4】:

        我在带有 .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 上。不会出现挂起问题。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-02-10
          • 1970-01-01
          • 2011-03-13
          • 1970-01-01
          • 2012-05-13
          • 2014-01-13
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多