首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OnCloseQuery能保护数据丢失吗?

OnCloseQuery能保护数据丢失吗?
EN

Stack Overflow用户
提问于 2022-11-17 07:57:58
回答 2查看 105关注 0票数 0

H1 --我编写了一个小进程,在使用Application.Terminate之前使用OnCloseQuery保存数据。我想知道,在发生停电或计算机崩溃的情况下,这是否足够。

代码语言:javascript
复制
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;

提前谢谢你。

编辑

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

代码语言:javascript
复制
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;
EN

回答 2

Stack Overflow用户

发布于 2022-11-17 17:08:05

这在发生电源故障或计算机崩溃时就足够了。

没关系,您请。

在回答了这个问题之后,让我们看看OnCloseQuery是在哪里触发的,这样您就可以感觉到您可能错过了什么:

  • (至少在Delphi 5中)当Windows会话即将结束时调用它,并要求每个正在运行的进程优雅地关闭:过程TCustomForm.WMQueryEndSession(var Message: TWMQueryEndSession);Message.Result := Integer(CloseQuery和CallTerminateProcs);end; 当用户选择结束会话或应用程序调用系统关闭函数之一时,就会发送WM_QUERYENDSESSION消息。如果任何应用程序返回零,则会话不会结束。
  • 当调用.Close()时--关闭一个窗口(窗体)的典型调用。
  • 当内部调用.CloseModal()时。

请记住,像TerminateProcess()这样简单的东西会杀死正在运行的程序,而不会让它仍然执行指令。此外,在主程序线程上使用SuspendThread()也可以无限地挂起它,因此您的代码也不会被执行。

票数 1
EN

Stack Overflow用户

发布于 2022-11-19 04:41:54

有人评论说,如果你失去电源或电脑崩溃,什么也帮不上忙。这不是完全正确的。但在这种情况下,唯一有帮助的是:

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

  • 自上次定期保存以来,您仍然会丢失任何未保存的数据(如果您经常保存的话,这将被最小化)。
  • 在定期保存期间,电源出现故障或计算机崩溃。根据您的要求,这可能是一个可以接受的风险,但避免此问题的方法是每次在不同的地方保存,也许在最近的定期保存成功完成之后删除以前的定期保存。

数据库通常支持事务(通常称为COMMITROLLBACK,参见),因此,当在保存数据期间发生停电时,它“只是”丢失,但从未覆盖或使以前的保存无效。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74471946

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档