[教程]QProfile教程之二:异步操作函数调用引用关系跟踪

在 QProfile 中,TQProfile.Calc 函数包含两个参数,我们先看下其具体声明:

 class function Calc(const AName: String; AStackRef: PQProfileStack = nil): TQProfileCalcResult;

这个函数有两个参数:

  • AName 用来标记当前函数的名称,对于 TQProfile 来说,这个名称由于是用户指定的,理论上可以是任意值,正常来说,一般我们对应函数名。
  • AStackRef 用来标记当前对应的调用的参考来源,是一个可选参数,默认为空。

而函数间的调用,我们可以分为同步调用和异步调用:

  • 对于同步调用,我们不需要任何额外处理,因为它们之间的调用关系是在同一个线程中有明确的顺序关系的。
  • 对于异步调用,由于函数可能不在同一个线程中执行,明显在调用栈中是看不到函数之间的调用顺序逻辑的。
    • 方式 1:直接将 AName 参数设置为 XXX#YY,其中 XXX 为原始调用函数名称
    • 方式 2:通过 AStackRef 参数设置为调用者,从而明确建立引用关系

示例

  1. 使用书签模式来处理引用
procedure TForm1.Button5Click(Sender: TObject);
begin
  TQProfile.Calc('TForm1.Button5Click');
  DoProfile(0);
  TThread.ForceQueue(nil,
    procedure
    begin
      TQProfile.Calc('TForm1.Button5Click.ForceQueue#TForm1.Button5Click');
      ShowMessage('Queued clicked');
    end);
end;

2. 使用 AStackRef 参数来处理引用

procedure TForm1.Button1Click(Sender: TObject);
begin
  // 定义一个局部变量缓存当前栈信息,以便 TThread.ForceQueue 中能够记录引用信息,如果不需要,刚可以忽略返回值
  var
  AProfile := TQProfile.Calc('TForm1.Button1Click').CurrentStack;
  DoProfile(0);
  TThread.ForceQueue(nil,
    procedure
    begin
      TQProfile.Calc('TForm1.Button1Click.ForceQueue', AProfile);
      ShowMessage('Queued clicked');
    end);
end;

输出结果

下面左右分别是书签或参数的输出结果,实际最终生成的效果是一致的:

[
  {
    "threadId":10128,
    "chains":[
      {
        "name":"TForm1.Button5Click",
        "maxNestLevel":0,
        "runs":1,
        "minTime":0,
        "maxTime":888,
        "totalTime":888,
        "avgTime":888,
        "children":[
          {
            "name":"TForm1.DoProfile",
            "maxNestLevel":32,
            "runs":1,
            "minTime":0,
            "maxTime":610,
            "totalTime":610,
            "avgTime":610
          }
        ]
      },
      {
        "name":"TForm1.Button5Click.ForceQueue",
        "maxNestLevel":0,
        "runs":1,
        "minTime":0,
        "maxTime":11459085,
        "totalTime":11459085,
        "avgTime":11459085,
        "refs":[
          "TForm1.Button5Click"
        ]
      }
    ]
  }
]
[
  {
    "threadId":848,    
    "chains":[
      {
        "name":"TForm1.Button1Click",
        "maxNestLevel":0,
        "runs":1,
        "minTime":0,
        "maxTime":786,
        "totalTime":786,
        "avgTime":786,
        "children":[
          {
            "name":"TForm1.DoProfile",
            "maxNestLevel":32,
            "runs":1,
            "minTime":0,
            "maxTime":551,
            "totalTime":551,
            "avgTime":551
          }
        ]
      },
      {
        "name":"TForm1.Button1Click.ForceQueue",
        "maxNestLevel":0,
        "runs":1,
        "minTime":0,
        "maxTime":11887781,
        "totalTime":11887781,
        "avgTime":11887781,
        "refs":[
          "TForm1.Button1Click"
        ]
      }
    ]
  }
]

滚动至顶部