簡體   English   中英

IdHTTPserver:共享ADOConnection

[英]IdHTTPserver: Share ADOConnection

我正在使用TIdHTTPServer創建一個簡單的Indy網絡服務器。 在幾乎所有請求中,服務器都需要與數據庫通信(通過TAdoConnection )。 看到數據庫連接在資源方面有點昂貴,我想創建一個池重用連接的池機制; 而不是在每個請求上建立連接。

我搜索的例子沒有成功。 這篇關於Embarcadero論壇的鏈接建議對TIdSchedulerOfThreadPoolTIdThreadWithTask的后代進行子類 但我仍然無法將它們全部融合在一起。

我是否需要覆蓋TIdSchedulerOfThreadPool.NewThread方法並讓它返回我的子類TIdThreadWithTask對象,而該對象又擁有自己的TAdoConnection對象?

有人有例子嗎? 我是否應該不擔心這一點,只是在每個請求上打開數據庫連接?

你為什么不親自管理游泳池?

你有一個連接列表。 它開始是空的。 每次請求到來時,您都會查找可用的連接(活動但未使用的連接)。 如果沒有找到,則創建一個並將其放入列表中,作為不可用。 請求結束后,將連接設置為可用。

在那里,做到了,不要后悔這樣做! 幾個值得關注的問題:

  • 始終牢記線程安全:
    • 查詢列表時
    • 查詢連接的可用性時
    • 設置連接的可用性時
  • 有時,檢查是否有太多未使用的連接可用,可能比您需要的多,因此必須將它們設置為不可用,從列表中刪除然后關閉。

您還必須確保在每個線程中正確設置COM並調用該對:CoInitialize / CoUnitialize

下面是要包含在項目中的示例單位。 在您的HTTP服務器構造函數中,只需創建自定義調度程序,Indy將使用它而不是默認值。

如果執行此操作,則將為COM正確初始化每個客戶端線程,並且還可以添加將由所有客戶端線程共享的其他項。

我還為每個連接創建了一個自定義TIdServerContext后代(並在HTTP Server構造函數中設置了ContextClass屬性。)不同類型的服務器具有不同的TIdServerContext后代,但它們都使用TsoIndyCOMEnabledSchedulerOfThread基本線程類,因為它們都執行某些COM分類。

我不會將ADO Connection放入Thread中,而是放入Context中......特別是如果你將其進一步放入線程池中。

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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM