【问题标题】:Can OnCloseQuery protect data lossOnCloseQuery 可以保护数据丢失吗
【发布时间】:2022-11-19 13:00:51
【问题描述】:

H1 我用OnCloseQuery 写了一个小程序来保存Application.Terminate 之前的数据。我想知道在电源故障或计算机崩溃的情况下这是否足够。

type
    TForm1 = class(TForm)
        abs: TABSDatabase;
        ABSTable1: TABSTable;
        .... 
        ABSTable6: TABSTable;
    ....    
var
Form1: TForm1;
isBusy : Boolean;
....
procedure TForm1.CloseTables;
 var
    x : Integer;
    dummy : TABSTable;
begin
     for x:=0 to ComponentCount-1 do
     begin
         if Components[x] is TABSDataSet then
             begin
                 if Components[x] is TABSTable  then
                 begin
                     dummy := (Components[x] as TABSTable);
                     if ((dummy.Active = True) and ((dummy.state = dsEdit) or (dummy.State = dsInsert))) then
                         begin
                             dummy.Post;
                             dummy.Active := False;
                         end
                       else
                         if dummy. Active = True then dummy.Close;                               
                 end;
             end;
     end;
end;

procedure TForm1.FormActivate(Sender: TObject);
begin
        if abs.Connected = True then isBusy := True else isBusy := False;
end;

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
    if isBusy = True then
        begin
            CanClose := False;
            CloseTables;
            abs.Connected := False;
            isBusy := False;
            Application.Terminate;
        end
        else CanClose := True;
end;

先感谢您。

编辑

我按照 David Heffernan 的建议修改了我的代码。

procedure TForm1.CloseTables;
 var
  x : Integer;
  dummy : TABSTable;
begin
   for x:=0 to ComponentCount-1 do
   begin
     if Components[x] is TABSDataSet then
       begin
         if Components[x] is TABSTable  then
          begin
            dummy := (Components[x] as TABSTable);
            if ((dummy.Active) and ((dummy.state = dsEdit) or (dummy.State = dsInsert))) then
              begin
                dummy.Post;
                dummy.Active := False;
              end
            else
              if dummy.Active then dummy.Close;
          end;
       end;
   end;
end;

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  if abs.Connected then
    begin
      CanClose := False;
      CloseTables;
      abs.Connected := False;
      Application.Terminate;
    end
  else CanClose := True;
end;

【问题讨论】:

  • 如果您删除所有这些代码,您将不会获得更好的行为,这对我来说一点也不明显。顺便说一句,不要写if foo = True then,写if foo then。也别写if foo then bar := True else bar := False,写bar := foo
  • 如果您的计算机断电或崩溃,则没有任何帮助。
  • 另外 isBusy 在这里是全局的,但应该是一个表单成员变量。这也可能没有必要。你不能直接测试abs.Connected吗?
  • 如果电源故障让您过于担心,请购买 ups
  • 假设您的青蛙模拟器应用程序中有一个类 {{TFrog}}。然后你创建一万个这样的实例——也就是说,你创建一万只在屏幕上跳来跳去的青蛙。每只青蛙都有自己的体重、颜色和年龄:这些是实例变量,也就是说,{{TFrog}} 类的每个实例——每只青蛙——都有自己的此类变量。另一方面,您的应用程序可能有一个全球时间或天气变量——在您的整个应用程序中只有一个这样的变量,无论您有多少只青蛙。

标签: delphi


【解决方案1】:

如果发生电源故障或计算机崩溃,这就足够了

一点都不。

回答完这个问题后,让我们看一下 OnCloseQuery 到底在哪里被触发,这样您就可以感觉到您还可能错过什么:

  • (至少在 Delphi 5 中)它在视窗会话即将结束,每个正在运行的进程都被要求优雅地关闭:
    procedure TCustomForm.WMQueryEndSession(var Message: TWMQueryEndSession);
    begin
      Message.Result := Integer(CloseQuery and CallTerminateProcs);
    end;
    

    WM_QUERYENDSESSION 消息在用户选择结束会话或应用程序调用其中一个系统关闭函数时发送。如果任何应用程序返回零,则会话不会结束。

  • 调用.Close() 时 - 关闭其中一个窗口(表单)的典型调用。
  • 在内部调用.CloseModal() 时。

请记住,像TerminateProcess() 这样简单的东西会杀死你正在运行的程序,而不让它有任何机会继续执行指令。此外,在主程序的线程上使用 SuspendThread() 也可以无限期地将其挂在那里,因此您的代码也不会执行。

【讨论】:

    【解决方案2】:

    有人评论说,如果您断电或计算机崩溃,没有任何帮助。这并不完全正确。但在这种情况下唯一可以提供帮助的是:

    • UPS(不间断电源),正如 David Heffernan 所提到的(这只会在停电的情况下提供帮助)。
    • 定期保存数据而不是等待表单或应用程序关闭。

    在后一种情况下,有两个潜在的问题:

    • 您仍然会丢失自上次定期保存以来所有未保存的数据(如果您经常保存,这些数据将被最小化)。
    • 断电或电脑死机期间定期保存。根据您的要求,这可能是一个可以接受的风险,但避免此问题的方法是每次都保存在不同的地方,也许在最新的定期保存成功完成后删除以前的定期保存。

    由于我没有使用过数据库,所以我不能说应该如何使用数据库来完成。

    【讨论】:

      猜你喜欢
      • 2015-02-28
      • 1970-01-01
      • 2021-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-04
      • 1970-01-01
      • 2023-03-10
      相关资源
      最近更新 更多