Delphi - 创建在自己的进程中运行的控件
嗨,
我有一个使用专有数据集访问数据库的控件。该数据库是旧的 ISAM 基础数据库。
该控件使用后台线程使用专有数据集查询数据库。
表单上将包含多个此类控件,每个控件都使用自己的线程来访问数据,因为它们都需要同时加载。
专有数据集通过显示 VCL TForm 来处理并发性,通知用户正在打开的表已被另一个用户锁定,并且数据集正在等待锁定被释放。
该表单上有一个取消按钮,可让用户取消锁定等待。
问题:
当在线程内使用专有数据集时,如果显示锁等待形式,应用程序将崩溃、挂起或给出一些错误。我怀疑这与 VCL 不是线程安全有关。
我已经通过同步 Dataset.Open 解决了这个问题,但这会占用主线程,直到 dataset.open 返回,这可能需要相当长的时间,具体取决于查询的复杂性。
我显示了一个模式进度条,让用户知道正在发生的事情,但我不喜欢这个想法,因为用户将等待进度条完成。
专有数据集代码被编译到主应用程序中,即它不存储在单独的 DLL 中。在开发过程的这个阶段,我们不允许更改锁定的工作方式或是否显示表单,因为我们距离发布太近了。
理想情况下,我希望 Dataset.open 在控件线程中运行,而不是使用主线程,但这似乎不太可能工作。
其他人可以建议解决方法吗?请。
HI
I have a control that accesses a database using proprietary datasets. The database is an old ISAM bases database.
The control uses a background thread to query the database using the proprietary datasets.
A form will have several of these controls on it, each using their own thread to access the data as they all need to load simultaneously.
The proprietary datasets handle concurrency by displaying a VCL TForm notifying the user that the table being opened is locked by another user and that the dataset is waiting for the lock to be released.
The form has a cancel button on it which lets the user cancel the lock wait.
The problem:
When using the proprietary datasets from within a thread, the application will crash, hang or give some error if the lock wait form it displayed. I suspect this is to do with the VCL not being thread safe.
I have solved the issue by synchronizing Dataset.Open however this holds up the main thread until the dataset.open returns, which can take a considerable amount of time depending on the complexity of the query.
I have displayed a modal progress bar which lets to user know that something it happening but I don't like this idea as the user will be sitting waiting for the progress bar to complete.
The proprietary dataset code is compiled into the main application, i.e. its not stored in a separate DLL. We are not allowed to change how the locking works or whether a form is displayed or not at this stage of the development process as we are too close to release.
Ideally I would like to have Dataset.open run in the controls thread as well instead of having the use the main thread, however this doesn't seem likely to work.
Can anyone else suggest a work around? please.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Fiber 不会对您有任何帮助,因为它们位于 Windows API 中只是为了帮助轻松移植以协作多任务处理为目的编写的旧代码。纤维基本上是协同例程的一种形式,它们都在同一个进程中执行,有自己的堆栈空间,并且它们之间的切换由用户代码控制,而不是由操作系统控制。这意味着它们之间的切换只能在安全的时间发生,因此不存在同步问题。 OTOH,这意味着一个线程中只能同时运行一根纤程,因此使用具有阻塞代码的纤程与从一个线程内调用阻塞代码具有相同的特征 - 应用程序变得无响应。
您可以将纤维与多个线程一起使用,但这可能很危险,并且与单独使用线程相比并没有带来任何好处。
我已在 VCL 应用程序中成功使用光纤,但仅用于特定目的。如果您想处理潜在的阻塞代码,请忘记它们。
至于您的问题 - 您应该创建一个仅用于显示目的的控件,并使用标准的进程间通信机制与访问数据库的另一个进程交换数据。
Fibers won't help you one bit, because they are in the Windows API solely to help ease porting old code that was written with cooperative multitasking in mind. Fibers are basically a form of co-routines, they all execute in the same process, have their own stack space, and the switching between them is controlled by the user code, not by the OS. That means that the switching between them can be made to occur only at times that are safe, so no synchronization issues. OTOH that means that only one fiber can be running within one thread at the same time, so using fibers with blocking code has the same characteristics as calling blocking code from within one thread - the application becomes unresponsive.
You could use fibers together with multiple threads, but that can be dangerous and doesn't bring any benefit over using threads alone.
I have used fibers successfully within VCL applications, but only for specific purposes. Forget about them if you want to deal with potentially blocking code.
As for your problem - you should make a control that is used for display purposes only, and which uses the standard inter-process communication mechanisms to exchange data with another process that accesses your database.
COM 对象可以在进程外模式下运行。可能在delphi中使用它们会更容易一些,然后是另一种IPC机制。
COM objects can run in out-of-process mode. May be in delphi it will be a bit easier to use them, then another IPC mechanisms.