如何防止Application RecoveryCallback()中出现死锁?

时间:2012-08-30 11:43:16

标签: multithreading delphi winapi indy

我已为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;

2 个答案:

答案 0 :(得分:1)

我不会那样写。程序停止响应时调用此函数。如你所知,它已停止响应,因为其他东西已经停留等待同一个关键部分。

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

答案 1 :(得分:1)

如果您将串行端口和CDS逻辑移出主线程,则可以降低应用无响应的可能性,并且可以启用ARR。主线程应仅用于UI逻辑,而在工作线程中更好地服务需要运行一段时间的业务逻辑。