在主线程中安全使用TAdsSettings对象,在其他线程中安全使用AdsQuery对象吗?

时间:2020-03-06 14:21:30  来源:igfitidea点击:

我有一个Win-CGI应用程序,当前正在转换为ISAPI。

该应用程序将TDataset后代用于扩展系统Advantage Database Server。

由于只能有一个TAdsSettings对象的实例,因此必须
在主线程中。

请求线程中需要TAdsQuery对象。

这项工作是否可以执行,即请求线程中的AdsQueries是否可以运行
从主菜单中的AdsSettings对象中选取全局设置
线程,这将是线程安全的吗?

解决方案

如果AdsQueries不在主线程中(例如,System.MainThreadID <> Windows.GetCurrentThreadID),请确保AdsQueries使用Synchronize直接访问TAdsSettings(或者使用消息传递系统在工作线程和主线程之间进行通讯而不是直接访问)。 )

是的,它将起作用。 TAdsSettings组件可修改Advantage Client Engine(ACE)中的设置,并且通过ISAPI,将加载所有线程使用的一个ACE实例。

但是,我不建议这样做。根据我们要更改的设置,直接调用ACE API会更有意义。例如,如果仅设置日期格式,则消除TAdsSettings组件并仅调用带有连接句柄的AdsSetDateFormat60更为有意义。摆脱了TAdsSettings组件,消除了许多设置ACE全局设置的调用。这些呼叫中的许多呼叫都必须具有同步对象,以在更改全局变量时保留所有连接。这将对性能产生负面影响,尤其是在像Web应用程序这样的多线程应用程序中。而是进行在指定的连接句柄上操作的调用。

我们可以通过引用TAdsConnection.Handle属性或者调用TAdsQuery.GetAceConnectionHandle方法来获取连接句柄。

我也在新闻组中问过这个问题:devzone.advantagedatabase.com,Advantage.Delphi

为了完整起见,我将在该线程的其余部分中添加更多问题/答案:

Question (Me):
  
  Many of the queries in threads are currently not attached to a 
  TAdsConnection object. I'm planning to create a connection for each 
  thread for these "orphan" queries to use, but it is a large application 
  and this will take time. I'm also pretty sure that the only non-default 
  property in the TAdsSettings object is the server-types set, which can 
  also be set in the connection component, thus once all queries are 
  linked to connections, the settings component wont be needed. I'll look 
  into calling the settings API directly as an alternative.
  
  In the meantime, I do have a question about threading and the queries 
  with no connection component assigned. I noted from the help files that 
  if queries in multiple threads share a single connection object, the 
  queries will be run in series rather than concurrently. With a 
  connection object in each thread, this should not be an issue, but I am 
  wondering about the queries which do not have a connection object 
  assigned. Will they be considered to be on independent connections from 
  the point of view of multithreading concurrency, or will they be 
  considered to be on the same connection and thus have to yield to each 
  other?
  
  Answer (Jeremy):
  
  You will need to address this.  They will just search a global list of connections 
  to find one with the same path, and they will use that connection.  Not good 
  in a multi-threaded application.

因此,根据Jeremy的回答,最好为每个线程至少创建一个TAdsConnection对象,并确保所有查询都添加到该对象,否则可能会发生序列化。