DelphiISAPIマルチスレッドログオブジェクトが正しく破棄されない

user14889477

ここで説明するマルチトレッドログソリューションを使用しようとしました:Delphiマルチスレッドファイルの書き込み:I / Oエラー32

TThreadFileLog上記のリンクで説明されているクラスをテストするために、空のDelphiISAPIプロジェクトを作成しました

インスタンス化logされたオブジェクトがfinalizeセクションに配置されると(IISアプリプールをリサイクルする)、ISAPI DLLが正しく解放されず、IIS全体を再起動する必要があります。

誰かがlogオブジェクトを正しく解放する方法を私に提案するかもしれませんか(私は機械エンジニアなので、プログラミングの原則が不足している可能性があります)。

unit LogUnit;

interface

uses Winapi.Windows, System.Classes, System.SysUtils, ThreadFileLog;

type
    PLogRequest = ^TLogRequest;
    TLogRequest = record
        LogText: String;
    end;

    TThreadFileLog = class(TObject)
    private
        FFileName: String;
        FThreadPool: TThreadPool;
        procedure HandleLogRequest(Data: Pointer; AThread: TThread);
    public
        constructor Create(const FileName: string);
        destructor Destroy; override;
        procedure Log(const LogText: string);
    end;

var log: TThreadFileLog;

implementation

{ TThreadFileLog }

constructor TThreadFileLog.Create(const FileName: string);
begin
    FFileName := FileName;
    FThreadPool := TThreadPool.Create(HandleLogRequest, 1);
end;

destructor TThreadFileLog.Destroy;
begin
    FThreadPool.Free;
    inherited;
end;

procedure TThreadFileLog.HandleLogRequest(Data: Pointer; AThread: TThread);
var
    Request: PLogRequest;
    F: TextFile;
begin
    Request := Data;
    try
        AssignFile(F, FFileName);
        if not FileExists(FFileName) then
            Rewrite(F)
        else
            Append(F);
        try
            Writeln(F, DateTimeToStr(Now) + ': ' + Request^.LogText);
        finally
            CloseFile(F);
        end;
    finally
        Dispose(Request);
    end;
end;

procedure TThreadFileLog.Log(const LogText: string);
var
    Request: PLogRequest;
begin
    New(Request);
    Request^.LogText := LogText;
    FThreadPool.Add(Request);
end;

initialization
    OutputDebugString('I N I T');
    log := TThreadFileLog.Create('C:\Temp\Test.log'); // <-- OK

finalization
    log.Free;                   // *** some IIS problem here when app-pool is recycled (need to restart the whole IIS)
    OutputDebugString('E N D'); // *** and this is never reached

end.

unit LogIsapiWebModuleUnit;

interface

uses System.SysUtils, System.Classes, Web.HTTPApp, Winapi.Windows;

type
    TWebModule1 = class(TWebModule)
        procedure WebModule1DefaultHandlerAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
    private
        { Private declarations }
    public
        { Public declarations }
    end;

var
    WebModuleClass: TComponentClass = TWebModule1;

implementation

{$R *.dfm}

uses LogUnit;

procedure TWebModule1.WebModule1DefaultHandlerAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
begin
    log.Log('WEBMODULE1 DefaultHandlerAction');
    Response.Content :=
        '<html>' +
        '<head><title>Web Server Application</title></head>' +
        '<body>Web Server Application</body>' +
        '</html>';
end;

Stijn Sandersの貴重な手がかりのおかげで、私は追加の検索を行い、おそらく次のような問題を解決する方法を見つけました。

library TestIsapiProject;

uses
    Winapi.Windows,
    Winapi.ActiveX,
    System.Win.ComObj,
    Web.WebBroker,
    Web.Win.ISAPIApp,
    Web.Win.ISAPIThreadPool,
    LogUnit in 'LogUnit.pas',
    TestIsapiMainWebModuleUnit in 'TestIsapiMainWebModuleUnit.pas' {WebModule1: TWebModule};

function TerminateExtension(dwFlags: dword): bool; stdcall;
begin
    // as per Microsoft "TerminateExtension provides a place to
    // put code that cleans up threads or de-allocate resources

    OutputDebugString('TerminateExtension BEGIN');
    log.Free;
    OutputDebugString('TerminateExtension END');

    Result := Web.Win.ISAPIThreadPool.TerminateExtension(dwFlags);
end;

exports
    GetExtensionVersion,
    HttpExtensionProc,
    TerminateExtension;

begin
    CoInitFlags := COINIT_MULTITHREADED;
    Application.Initialize;
    Application.WebModuleClass := WebModuleClass;
    Application.Run;
end.

また、問題を正確に説明し、この他の解決策を提案するこの記事見つけましたしかし、私が確認できる限り、DoTerminateは呼び出されないようです。

library TestIsapiProject;

uses
    Winapi.Windows,
    Winapi.ActiveX,
    System.Win.ComObj,
    Web.WebBroker,
    Web.Win.ISAPIApp,
    Web.Win.ISAPIThreadPool,
    LogUnit in 'LogUnit.pas',
    TestIsapiMainWebModuleUnit in 'TestIsapiMainWebModuleUnit.pas' {WebModule1: TWebModule};

procedure DoTerminate;
begin
    // free global objects and wait/terminate threads here
  
    OutputDebugString('TerminateExtension BEGIN');
    log.Free;
    OutputDebugString('TerminateExtension END');
end;

exports
    GetExtensionVersion,
    HttpExtensionProc,
    TerminateExtension;

begin
    CoInitFlags := COINIT_MULTITHREADED;
    Application.Initialize;
    Application.WebModuleClass := WebModuleClass;
    TISAPIApplication(Application).OnTerminate := DoTerminate; // added
    Application.Run;
end.

ありがとう。

Stijn Sanders

ISAPI DLLは関数TerminateExtensionをエクスポートしますか?そこからすべてのクリーンアップコードを呼び出し、finalizationセクションに依存せずに作業を行うことをお勧めします

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

グローバル オブジェクトは、すべてのスレッド ローカル ストレージ オブジェクトが破棄された後に破棄されることが保証されていますか?

分類Dev

マルチスレッドサーバーは、複数のクライアントが接続しようとすると、「破棄されたオブジェクトにアクセスできません」というエラーを表示します

分類Dev

使い捨てオブジェクトで正しく呼び出されないように破棄します

分類Dev

スコープの後でスレッドオブジェクトが破棄されないのはなぜですか?

分類Dev

カスタムビットマップオブジェクトがPictureBoxに正しく表示されない

分類Dev

Android-メソッドが終了した後でもリスナーオブジェクトが破棄されない方法

分類Dev

マルチレベルオブジェクトでAngular6プロパティバインディングが正しく機能しない

分類Dev

メソッドでスレッドが開始されているオブジェクトを破棄すると、Thread.Abort()を呼び出す必要がなくなります。

分類Dev

KableExtraテーブルオブジェクトからRノートブック形式で数学記号が正しくレンダリングされない

分類Dev

CとC ++の混合コードプログラミングで例外をキャッチした後、オブジェクトは破棄されません

分類Dev

このプログラムで同じオブジェクトにデッドロックがない理由-Javaマルチスレッド

分類Dev

PythonとNumba:解放されたオブジェクトのチェックサムが正しくない

分類Dev

マルチスレッド:havaのリソースに基づく動的なオブジェクトロック

分類Dev

これらのオブジェクトが破棄されない理由

分類Dev

オブジェクトが破棄された場合、MouseLeaveトリガーをブロックします

分類Dev

Pyopenglテクスチャが正しくレンダリングされず、オブジェクトが灰色で塗りつぶされています

分類Dev

アクティビティが破棄されてから再作成されると、オブザーバーが呼び出されず、ポストバリューがバックグラウンドスレッドから機能しない

分類Dev

マルチスレッド中にプログレスバーに正しい値が表示されない

分類Dev

マルチスレッド:変更されたオブジェクトの出力が期待どおりにならない

分類Dev

コード分析で「オブジェクトを複数回破棄しないでください」と表示されるのはなぜですか。

分類Dev

オブジェクトが破棄されるとaudio.play()が機能しない

分類Dev

オブジェクトの破棄では、どのプロパティがスキップされますか?

分類Dev

Angular 6 / PrimeNg6でチェックボックスとラジオボタンが正しくレンダリングされない

分類Dev

部分的に構築されたオブジェクト/マルチスレッド

分類Dev

GCC:オブジェクトファイルが破棄されない理由を見つける方法

分類Dev

角度モデルオブジェクトが正しくマップされていません

分類Dev

ES6でのマルチレベルオブジェクトの破棄

分類Dev

タスクが非同期で実行されている間にオブジェクトを破棄します

分類Dev

オリジンクロスオリジンリードブロッキング(CORB)が原因で、JSONAPIがフェッチを介して取得されない

Related 関連記事

  1. 1

    グローバル オブジェクトは、すべてのスレッド ローカル ストレージ オブジェクトが破棄された後に破棄されることが保証されていますか?

  2. 2

    マルチスレッドサーバーは、複数のクライアントが接続しようとすると、「破棄されたオブジェクトにアクセスできません」というエラーを表示します

  3. 3

    使い捨てオブジェクトで正しく呼び出されないように破棄します

  4. 4

    スコープの後でスレッドオブジェクトが破棄されないのはなぜですか?

  5. 5

    カスタムビットマップオブジェクトがPictureBoxに正しく表示されない

  6. 6

    Android-メソッドが終了した後でもリスナーオブジェクトが破棄されない方法

  7. 7

    マルチレベルオブジェクトでAngular6プロパティバインディングが正しく機能しない

  8. 8

    メソッドでスレッドが開始されているオブジェクトを破棄すると、Thread.Abort()を呼び出す必要がなくなります。

  9. 9

    KableExtraテーブルオブジェクトからRノートブック形式で数学記号が正しくレンダリングされない

  10. 10

    CとC ++の混合コードプログラミングで例外をキャッチした後、オブジェクトは破棄されません

  11. 11

    このプログラムで同じオブジェクトにデッドロックがない理由-Javaマルチスレッド

  12. 12

    PythonとNumba:解放されたオブジェクトのチェックサムが正しくない

  13. 13

    マルチスレッド:havaのリソースに基づく動的なオブジェクトロック

  14. 14

    これらのオブジェクトが破棄されない理由

  15. 15

    オブジェクトが破棄された場合、MouseLeaveトリガーをブロックします

  16. 16

    Pyopenglテクスチャが正しくレンダリングされず、オブジェクトが灰色で塗りつぶされています

  17. 17

    アクティビティが破棄されてから再作成されると、オブザーバーが呼び出されず、ポストバリューがバックグラウンドスレッドから機能しない

  18. 18

    マルチスレッド中にプログレスバーに正しい値が表示されない

  19. 19

    マルチスレッド:変更されたオブジェクトの出力が期待どおりにならない

  20. 20

    コード分析で「オブジェクトを複数回破棄しないでください」と表示されるのはなぜですか。

  21. 21

    オブジェクトが破棄されるとaudio.play()が機能しない

  22. 22

    オブジェクトの破棄では、どのプロパティがスキップされますか?

  23. 23

    Angular 6 / PrimeNg6でチェックボックスとラジオボタンが正しくレンダリングされない

  24. 24

    部分的に構築されたオブジェクト/マルチスレッド

  25. 25

    GCC:オブジェクトファイルが破棄されない理由を見つける方法

  26. 26

    角度モデルオブジェクトが正しくマップされていません

  27. 27

    ES6でのマルチレベルオブジェクトの破棄

  28. 28

    タスクが非同期で実行されている間にオブジェクトを破棄します

  29. 29

    オリジンクロスオリジンリードブロッキング(CORB)が原因で、JSONAPIがフェッチを介して取得されない

ホットタグ

アーカイブ