【问题标题】:Crystal Reports - Is TCrpe for Delphi threadsafe?Crystal Reports - Delphi 的 TCrpe 是线程安全的吗?
【发布时间】:2011-03-11 16:14:06
【问题描述】:

Short:可以在非VCL主线程中执行TCrpe组件吗?

Long:我使用 TCrpe 组件为 Crystal Reports 创建报表。 到目前为止,我在 VCL 主线程中使用了该组件,一切都很好。

但现在我将组件移动到后台线程中。组件一次只有1个实例,并且只能被一个单线程访问,不是VCL主线程。

在我的测试环境中,一切似乎都很好。 但是在生产环境中应用时常崩溃:访问违规;无效的指针操作;列出索引超出范围的异常。异常几乎可以在任何地方发生,而且我并不总是得到异常堆栈跟踪。

那么:可以在非 VCL 主线程中执行 TCrpe 组件吗?

看了源码,里面用到了一些GUI相关的东西,让我怀疑。他们甚至打电话给

while not PrintEnded do Application.HandleMessage;

从那里。实际上,由于我的报告设置,此代码路径未激活;但是,这让我想知道 TCrpe 组件是否完全适合在后台线程中使用。

此外,对于某些报告,TCrpe 组件会显示一个自己的表单,供用户输入其他报告参数。这是否表明他们正在搞乱主消息事件循环?还是他们正在为该表单使用自己的消息队列?

【问题讨论】:

  • while not PrintEnded do Application.HandleMessage 将在打印机回调中,并在打印时保持您的 UI 响应。
  • @David 是的,但是从不是 VCL 主线程的线程中调用它是致命的,不是吗?
  • 不一定。如果你在一个没有创建任何窗口的线程上调用它,那么甚至可能没有消息队列,它是无害的。

标签: multithreading delphi crystal-reports


【解决方案1】:

如果这个组件显示任何形式,那么它正在使用 VCL 组件。应用程序中对 VCL 的所有使用都必须在同一个线程中完成,这是 VCL 的要求。

您需要找到一个在主应用程序线程中运行所有 VCL 代码的设计。

说了这么多,这并不能解释为什么你看到崩溃只是远离测试环境。关于线程的建议是有效的,但您很可能遇到了不同的问题。

【讨论】:

  • 好吧,其实我不确定组件是否显示表单(用于输入报告参数)或加载的dll是否显示表单。
  • @nang 如果在工作线程之外运行 CR 是一个问题,那么我相信它会导致您的测试环境出现问题。我所说的建议是,您需要遵守 VCL 线程规则,但我怀疑您的问题出在其他地方。
  • 关于测试环境和生产环境的区别:我同意。但是,可能是我根本无法重现现实生活中用户的交互模式。另外,生产环境是Citrix/Windows2000服务器,测试环境是Vista。
  • @nang 为了排除 VCL 线程问题,您必须确定是否创建了任何带有窗口句柄的 VCL 组件,例如TWinControl 后代。
  • @david 如果我知道该错误不在我的线程代码中,我肯定会更喜欢它。但还有什么理由呢?旧的单线程版本的应用程序运行良好。然后我引入了后台线程,问题就开始了。所以我的赌注是:该组件不是线程安全的,或者我的线程代码中有错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-17
  • 2010-10-14
  • 2015-02-15
  • 1970-01-01
  • 2010-09-09
相关资源
最近更新 更多