1

ARRのアプリケーションを登録しました。IdTCPServer私のアプリケーションには、を使用してシリアル ポートからデータを読み取り、VSPEそれを に追加するがあると仮定しますClientDataSet。メイン スレッドがフリーズすると、ARR は ApplicationRecoveryCallback() を呼び出します。IdTCPServerリカバリ コールバック関数に安全にアクセスできますか? ClientDataSet再起動する前にディスクに保存できるように停止したい。このように関数を単純に記述できますか?

function RecoveryFunction(pvParameter: Pointer): DWORD; stdcall;
var
  ContinueRecovery: Boolean;
begin
  Result := 0; // happy compiler ;-)
  repeat
    ApplicationRecoveryInProgress(ContinueRecovery);
    if not ContinueRecovery then
      ApplicationRecoveryFinished(False);
  until frmInstrument.CriticalSection.TryEnter;
  frmInstrument.IdTCPServer.Active := False;
  frmInstrument.CDS.SaveToFile(RecoveryFile);
  ApplicationRecoveryFinished(True);
end;
4

2 に答える 2

1

シリアル ポートと CDS ロジックをメイン スレッドの外に移動すると、アプリが応答しなくなり、ARR が開始される可能性が減ります。メイン スレッドは UI ロジックのみに使用する必要があります。実行に時間がかかるビジネス ロジックは、代わりにワーカー スレッドで処理することをお勧めします。

于 2012-08-30T15:14:54.980 に答える
1

私ならそんなことは書きません。この関数は、プログラムが応答を停止したときに呼び出されます。ご存知のように、同じクリティカル セクションを待機している他の何かが既にスタックしているため、応答が停止しています。

プログラムがハングしたときでもデータにアクセスできるようにしたい場合は、データの読み取りがいつ許可されているかを検出するロックフリーの方法が必要です。トランザクション ログ モデルを使用します。有効なデータの量を示すものを原子的に更新します。回復機能に入るときは、その値を読み取り、使用可能な限り保存します。それが壊れていないこと、そしてそもそもプログラムがクラッシュした理由であると確信できないため、それ以上は読まないでください。

于 2012-08-30T12:22:35.273 に答える