![](https://csdnimg.cn/release/download_crawler_static/13986158/bg4.jpg)
二、使用自定义托管记录自动执行可恢复的操作
有那些常见的 try..finally 块,您一遍又一遍地写。例如,进入和离开关键部分以保护资
源免受多个线程的侵害,或者调用 BeginUpdate 和 EndUpdate 有效地批量更新 FireMonkey
控件。这些类型的“可恢复”操作可以通过 Delphi10.4 中引入的新“自定义管理记录”功能
自动进行。
1、关于自定义托管记录
如果您还不熟悉 Custom Managed Records(自定义托管记录,以下简称 CMR),那么请
看一下我以前关于使用 CMR 包装 C(++)API 的文章。
作为简短回顾,请考虑以下 CMR:
type
TFoo = record
public
class operator Initialize(out ADest: TFoo);
class operator Finalize(var ADest: TFoo);
class operator Assign(var ADest: TFoo;
const [ref] ASrc: TFoo);
end;
然后,当您声明这样的记录时,Delphi 将自动调用 Initialize 运算符,而当记录超出范围
时将自动调用 Finalize。调用 Assign 运算符可将一条记录复制到另一条记录。您不必全部使
用 3 个运算符,但至少需要一个运算符才能创建 CMR。
现在,当您编写以下代码时:
begin
var Foo1: TFoo;
var Foo2 := Foo1;
end;
然后,Delphi 会将其转换为幕后的以下代码(请注意,该代码虽然不会编译):
begin
var Foo1, Foo2: TFoo;
TFoo.Initialize(Foo1);
try
TFoo.Initialize(Foo2);
try
TFoo.Assign(Foo2, Foo1);
finally
TFoo.Finalize(Foo2);
end;
finally
TFoo.Finalize(Foo1);
end;
end;
Delphi 将自动插入 try..finally 语句,以确保始终调用 Finalize 运算符。这是自动化“可恢
复”操作的关键。
有 关 “ 自 定 义 托 管 记 录 ” 的 更 多 信 息 , 请 查 看 官 方 文 档
(http://docwiki.embarcadero.com/RADStudio/Sydney/en/Custom_Managed_Records),我以前的
文 章 或 Internet 上 的 其 他 资 源
(https://blog.grijjy.com/2020/07/20/wrapping-c-apis-with-custom-managed-records/)。
这篇文章的其余部分显示了三种使用 CMR 自动执行可恢复操作的方法。
1)自动 BeginUpdate 和 EndUpdate