0

你好

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

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

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

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

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

问题:

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

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

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

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

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

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

4

2 回答 2

1

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

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

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

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

于 2011-03-20T08:46:15.760 回答
0

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

于 2011-03-20T09:27:30.667 回答