【问题标题】:Delphi - Creating a control that runs in its own processDelphi - 创建一个在自己的进程中运行的控件
【发布时间】:2011-03-19 23:42:46
【问题描述】:

我有一个使用专有数据集访问数据库的控件。该数据库是一个旧的 ISAM 基础数据库。

控件使用后台线程使用专有数据集查询数据库。

一个表单上会有几个这样的控件,每个都使用自己的线程来访问数据,因为它们都需要同时加载。

专有数据集通过显示 VCL TForm 通知用户正在打开的表已被另一个用户锁定并且数据集正在等待释放锁定来处理并发。

表单上有一个取消按钮,可以让用户取消锁定等待。

问题:

在线程中使用专有数据集时,如果显示锁定等待形式,应用程序将崩溃、挂起或给出一些错误。我怀疑这与 VCL 不是线程安全的有关。

我已经通过同步 Dataset.Open 解决了这个问题,但是这会阻止主线程直到 dataset.open 返回,这可能需要相当长的时间,具体取决于查询的复杂性。

我展示了一个模态进度条,让用户知道它正在发生的事情,但我不喜欢这个想法,因为用户会坐等进度条完成。

专有数据集代码被编译到主应用程序中,即它不存储在单独的 DLL 中。在开发过程的这个阶段,我们不允许更改锁定的工作方式或是否显示表单,因为我们离发布太近了。

理想情况下,我希望 Dataset.open 在控制线程中运行,而不是使用主线程,但这似乎不太可能工作。

其他人可以建议解决方法吗?请。

【问题讨论】:

  • 你的问题对我来说毫无意义。要在单独的进程中创建控件,请将其放在单独的应用程序中。纤维与 VCL 一起使用并不比线程更安全。根本不清楚为什么 ISAM 数据库的锁定消息会成为问题。它直接使用VCL吗?如果有,怎么做?
  • 我只是想知道是否有可能拥有一个在单独的进程中运行但以另一个进程的形式显示的控件,并且在没有单独的可执行文件的情况下执行此操作。 ISAM 数据集组件显示一个锁定消息,该消息基本上是一个带有取消按钮的 TForm。锁定消息通知用户正在打开的表当前已被另一个用户锁定。然后用户可以选择等待或按下取消按钮。它的代码从为什么回到 DOS 时代移植到 windows 和我无法更改的东西。
  • 可以让来自不同进程的 UI 出现在单个父容器中。考虑 Chrome 或 IE8。我不认为你需要这样做。您可以在后台线程中使用 UI,只要该 UI 是完全隔离的。如果这个其他代码是作为 DLL 提供的,那么我不明白你为什么会遇到问题。

标签: multithreading delphi vcl tform


【解决方案1】:

Fibers 对您一点帮助都没有,因为它们在 Windows API 中只是为了帮助轻松移植考虑到协作多任务处理而编写的旧代码。 Fiber 基本上是协程的一种形式,它们都在同一个进程中执行,有自己的堆栈空间,它们之间的切换由用户代码控制,而不是由操作系统控制。这意味着它们之间的切换只能在安全的时候进行,因此不会出现同步问题。 OTOH 这意味着在一个线程中只能同时运行一根纤程,因此使用带有阻塞代码的纤程与从一个线程内调用阻塞代码具有相同的特性 - 应用程序变得无响应。

您可以将纤维与多个线程一起使用,但这可能很危险,并且不会比单独使用线程带来任何好处。

我在 VCL 应用程序中成功使用了光纤,但仅用于特定目的。如果您想处理潜在的阻塞代码,请忘记它们。

至于您的问题 - 您应该制作一个仅用于显示目的的控件,并使用标准的进程间通信机制与访问您的数据库的另一个进程交换数据。

【讨论】:

  • 抱歉,我不太明白您所说的与访问您的数据库的另一个进程交换数据是什么意思?你的意思是创建另一个进程来访问数据库并使用 WM_COPYDATA 传递数据(对不起,我不记得消息叫什么)?这可以在没有单独的可执行文件的情况下完成吗?有点像创建一个虚拟进程并在运行一些代码时为其附加一个线程..
  • @no spoon:您询问了让控件在自己的进程中运行的问题。一个进程必须有一个可执行文件——相同的或不同的。如果您生成相同可执行文件的另一个实例(可能带有命令行开关),那么您将不需要另一个实例。然而,所有这些都与纤维无关。你应该澄清你的问题。
  • 对于任何想知道为什么这似乎与问题完全无关的人:未经编辑的问题被标记为纤维,并专门询问它们作为可能的解决方案。我会留下答案,因为似乎对纤维有很多误解。注意:与 VCL 一起使用时,它们并没有不安全或危险等。
【解决方案2】:

COM 对象可以在进程外模式下运行。可能在delphi中使用起来会容易一些,然后是另一种IPC机制。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多