在不锁定应用程序的情况下将详细信息输出到备忘录的最佳方法是什么

问题描述

我正在开发一个基于 Delphi 10 Seattle 的应用程序,该应用程序使用 FireDAC 的工具集执行多个任务,以在 Firebird 上执行备份,还原和维护例程。 strong>数据库

此工具集中包含的组件( TFDIBBackup,TFDIBRestore和TFDIBValidade )均具有 Verbose 选项,可让您截取输出并能够输出到某个地方以便阅读。

我正在尝试将其输出到备忘录中,但是我遇到了一些问题。

主要问题是:数据库越大,进程速度显着降低,输出的行越多,与备份/还原数据库所花费的时间直接相关。如果完全禁用详细,则该过程所花费的时间将减少到总时间的10%。太疯狂了。

在实验过程中,我发现如果我使用另一个线程将详细信息输出到备忘录,则该过程不会对性能造成太大的影响,就像非详细选项的90%一样,这是大。但是我遇到了一个问题,使用线程使应用程序创建某种类型的线程堆栈,这些线程最终将输出到备忘录中,但是问题是流程本身已经完成,并且行将继续输出到备忘录很久了。

如果我不使用线程来执行此操作,则该过程将对其性能产生重大影响,并且该应用程序实质上将被锁定,直到该过程完成为止。

有人知道有什么好方法可以输出此工具集的详细信息而不会锁定UI或导致我上面解释的问题吗?

解决方法

我决定实施 AmigoJack 的建议,即使用AllocConsole()Writeln()来显示Firebird的详细输出。它运行良好,并且不会锁定我的应用程序的GUI。

要防止用户在关闭控制台时关闭应用程序,您可以获取该控制台的句柄,然后删除关闭按钮。

您将需要先声明此函数:

function GetConsoleWindow: HWND; stdcall; external kernel32;

这是分配新控制台然后隐藏按钮的代码:

var
  handle: HWND;
  consoleMenuItem: HMENU;
begin
  AllocConsole();

  handle := GetConsoleWindow;

  if IsWindow(handle) then
  begin
    consoleMenuItem := GetSystemMenu(Handle,False);

    if IsMenu(consoleMenuItem) then
    begin
      DeleteMenu(consoleMenuItem,SC_CLOSE,MF_BYCOMMAND);
    end;
  end;
end;

请记住要为用户添加一种调用FreeConsole()的方式,以便在您不再需要控制台或自行调用该控制台时摆脱它。