我有一个正在转换为 ISAPI 的 Win-CGI 应用程序。
该应用程序使用 Extended Systems Advantage Database Server 的 TDataset 后代。
由于 TAdsSettings 对象只能有一个实例,因此它必须在主线程中。
请求线程中需要 TAdsQuery 对象。
这会起作用吗?也就是说,请求线程中的 AdsQueries 是否会从主线程中的 AdsSettings 对象中获取全局设置,这是否是线程安全的?
我有一个正在转换为 ISAPI 的 Win-CGI 应用程序。
该应用程序使用 Extended Systems Advantage Database Server 的 TDataset 后代。
由于 TAdsSettings 对象只能有一个实例,因此它必须在主线程中。
请求线程中需要 TAdsQuery 对象。
这会起作用吗?也就是说,请求线程中的 AdsQueries 是否会从主线程中的 AdsSettings 对象中获取全局设置,这是否是线程安全的?
是的,它会起作用。TAdsSettings 组件修改 Advantage Client Engine (ACE) 中的设置,并且使用 ISAPI 将加载一个所有线程都使用的 ACE 实例。
但是,我不会推荐它。根据您正在更改的设置,直接调用 ACE API 会更有意义。例如,如果您只设置日期格式,则删除 TAdsSettings 组件并只调用 AdsSetDateFormat60 会更有意义,它需要一个连接句柄。摆脱 TAdsSettings 组件消除了设置 ACE 全局设置的大量调用。其中许多调用必须有一个同步对象来在全局更改时阻止所有连接。这将对性能产生负面影响,尤其是在 Web 应用程序等多线程应用程序中。而是进行对指定连接句柄进行操作的调用。
您可以通过引用 TAdsConnection.Handle 属性或调用 TAdsQuery.GetAceConnectionHandle 方法来获取连接句柄。
如果 AdsQueries 不在主线程中(即),请确保 AdsQueries 使用 Synchronize 直接访问 TAdsSettings(或使用消息系统在工作线程和主线程之间进行通信,而不是直接访问System.MainThreadID <> Windows.GetCurrentThreadID
)
我也在新闻组中问过这个问题:devzone.advantagedatabase.com, Advantage.Delphi
为了完整起见,我将从该线程的其余部分添加更多问题/答案:
问我):
线程中的许多查询当前未附加到 TAdsConnection 对象。我计划为每个线程创建一个连接以供这些“孤立”查询使用,但它是一个大型应用程序,这需要时间。我也很确定 TAdsSettings 对象中唯一的非默认属性是服务器类型集,它也可以在连接组件中设置,因此一旦所有查询都链接到连接,就不需要设置组件。我将考虑直接调用设置 API 作为替代方案。
同时,我确实对线程和未分配连接组件的查询有疑问。我从帮助文件中注意到,如果多个线程中的查询共享一个连接对象,则查询将连续运行而不是同时运行。在每个线程中都有一个连接对象,这应该不是问题,但我想知道没有分配连接对象的查询。从多线程并发的角度来看,它们会被认为是在独立的连接上,还是会被认为是在同一个连接上,因此必须相互让步?
答案(杰里米):
您将需要解决这个问题。他们将只搜索全局连接列表以找到具有相同路径的连接,然后他们将使用该连接。在多线程应用程序中不好。
因此,根据 Jeremy 的回答,最好为每个线程创建至少一个 TAdsConnection 对象,并确保所有查询都附加到它,否则可能会发生序列化。