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

我不会那样写的。当您的程序停止响应时调用此函数。如您所知,它已停止响应,因为其他东西已经卡在等待相同的关键部分。

如果您希望即使在程序挂起时也能访问您的数据,那么您需要一种无锁方式来检测何时允许您读取数据。使用事务日志模型。以原子方式更新指示您的数据有多少是有效的。当您进入恢复功能时,读取该值,并尽可能多地保存它所说的可用值。不要费心阅读超出这一点的内容,因为您无法确定它没有损坏以及程序崩溃的原因。

于 2012-08-30T12:22:35.273 回答
1

如果您将串行端口和 CDS 逻辑移出主线程,则可以降低应用程序变得无响应并完全启动 ARR 的可能性。主线程应该只用于 UI 逻辑,需要一段时间才能运行的业务逻辑最好在工作线程中提供。

于 2012-08-30T15:14:54.980 回答