OmniThreadLibrary:如何在不使用匿名过程的情况下运行Parallel.For.Execute?

时间:2019-12-17 16:54:38

标签: delphi omnithreadlibrary

Parallel.For的Execute方法具有TOmniIteratorDelegate参数。但是我不确定如何将过程分配给该类型的变量。这样做的原因是我不想使用匿名过程。

这可能吗?如果是,有人可以告诉我该怎么做吗?

type
  TBookmark = record
    URL: String;
    PageTitle: String;
  end;

  PBookmark = ^TBookmark;

var
  FBookmarkList: TThreadList<PBookmark>;

procedure TfmMain.FormCreate(Sender: TObject);
begin
  FBookmarkList := TThreadList<PBookmark>.Create;

end;

procedure TfmMain.FormDestroy(Sender: TObject);
var
  B: PBookmark;
  L: TList<PBookmark>;
begin
  L := FBookmarkList.LockList;
  for B in L do
    Dispose(B);
  FBookmarkList.UnlockList;
  FBookmarkList.Free;
end;

procedure SetValue(const Value: TOmniValue);
begin
  // P := Value.ToRecord<PBookmark>;
  // P.PageTitle := P.URL;

end;

procedure TfmMain.btRefreshClick(Sender: TObject);
var
  L: TList<PBookmark>;
  P: TOmniIteratorDelegate<PBookmark>;
  t: IOmniParallelLoop<PBookmark>;
begin

  P := TOmniIteratorDelegate<PBookmark>(Addr(SetValue)); // <---- Program crashes at runtime on this line!

  L := FBookmarkList.LockList;
  try
    t := Parallel.ForEach<PBookmark>(L).NumTasks(5);
    t.Execute(P);

    vstBkmk.Clear;
    FvstBkmkIter := 0;
    vstBkmk.RootNodeCount := L.Count;
  finally
    FBookmarkList.UnlockList;
  end;

end;

1 个答案:

答案 0 :(得分:2)

我通过更改SetValue过程的定义使其工作,如下面的代码所示。感谢 David Heffernan 为我指明了正确的方向。

procedure SetValue(const Value: PBookmark);
var
  P: PBookmark;
begin
  Value.PageTitle := Value.URL;
end;

procedure TfmMain.btRefreshClick(Sender: TObject);
var
  L: TList<PBookmark>;
  P: TOmniIteratorDelegate<PBookmark>;
  t: IOmniParallelLoop<PBookmark>;
begin

  P := SetValue;

  L := FBookmarkList.LockList;
  try
    t := Parallel.ForEach<PBookmark>(L).NumTasks(5);
    t.Execute(P);

    vstBkmk.Clear;
    FvstBkmkIter := 0;
    vstBkmk.RootNodeCount := L.Count;
  finally
    FBookmarkList.UnlockList;
  end;

end;