首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >IdHTTPserver:共享ADOConnection

IdHTTPserver:共享ADOConnection
EN

Stack Overflow用户
提问于 2011-09-16 15:25:54
回答 2查看 1.2K关注 0票数 2

我正在使用TIdHTTPServer.创建一个简单的Indy Indy服务器对于几乎所有的请求,服务器都需要与数据库通信(通过TAdoConnection). )。考虑到数据库连接在资源方面有些昂贵,我想创建一个池机制来重用连接,而不是在每个请求上建立连接。

我找不到例子。Embarcadero论坛上的TIdSchedulerOfThreadPoolTIdThreadWithTask.的子类但我还是不能把这一切都搞清楚。

我是否需要重写TIdSchedulerOfThreadPool.NewThread方法并让它返回我的子类TIdThreadWithTask对象,而这个对象又会有它自己的TAdoConnection对象?

有人举过例子吗?我甚至不应该担心这一点,只需在每个请求上打开数据库连接?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-09-16 15:31:51

你为什么不自己管理游泳池呢?

你有一个连接列表。一开始是空的。每次请求出现时,您都会查找可用的连接(活动但未被使用的连接)。如果没有找到,则创建一个,并将其放在列表中,作为不可用。一旦请求结束,您将连接设置为可用。

去过那里,做过那件事,一点也不后悔!令人关切的几点:

  • 始终牢记线程安全:
    • 当您查询列表时
    • 当您查询连接的可用性时
    • 设置连接的可用性时

  • 不时地,检查是否有太多可用的未使用连接,可能有更多超出您需要的连接,因此必须将它们设置为不可用,从列表中删除,然后关闭。
票数 4
EN

Stack Overflow用户

发布于 2011-09-16 16:47:43

您还必须确保在每个线程中正确地设置COM,并调用这对线程: CoInitialize/CoUnitialize

下面是要包含在项目中的一个示例单元。在您的HTTP服务器构造函数中,只需创建您的自定义调度程序,Indy就会使用它而不是默认的。

如果这样做,那么每个客户端线程都将被正确地初始化为COM,并且还可以添加将由所有客户端线程共享的其他项。

我还为每个连接创建了一个自定义的TIdServerContext后代(并在HTTP构造函数中设置了ContextClass属性)。不同类型的服务器有不同的TIdServerContext后代,但它们都使用TsoIndyCOMEnabledSchedulerOfThread基线程类,就像它们都使用某种COM一样。

我不会将ADO连接放入线程中,而是将其放入Context...especially中,如果您将其进一步放入线程池中。

代码语言:javascript
复制
unit ExampleStackOverflow;

interface

uses
  SysUtils, Classes,
  ActiveX,
  IdThread, IdSchedulerOfThreadDefault;

type
  //Meant to be used with a custom TIdSchedulerOfThreadDefault descendant
  //to ensure COM support on child threads.
  TsoIndyComThreadWithTask = class(TIdThreadWithTask)
  protected
    //Ensure COM is setup before client connection/thread work
    procedure BeforeExecute; override;
    //Graceful COM cleanup on client connection/thread
    procedure AfterExecute; override;
  end;


  TsoIndyCOMEnabledSchedulerOfThread = class(TIdSchedulerOfThreadDefault)
  public
    constructor Create(AOwner:TComponent); reintroduce;
  end;



implementation

procedure TsoIndyComThreadWithTask.BeforeExecute;
begin
  CoInitialize(nil);
  inherited;
end;


procedure TsoIndyComThreadWithTask.AfterExecute;
begin
  inherited;
  CoUninitialize();
end;


constructor TsoIndyCOMEnabledSchedulerOfThread.Create(AOwner:TComponent);
begin
  inherited;
  //the whole reason for overriding default scheduler of thread is to setup COM
  //on client threads
  ThreadClass := TsoIndyComThreadWithTask;
  Name := Name + 'COMEnabledScheduler';
end;
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7446936

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档