【问题标题】:Order of TForm creation and destruction and threadsTForm 创建和销毁的顺序和线程
【发布时间】:2013-05-04 17:34:13
【问题描述】:

我有一个线程调用某种形式的函数来更新这个表单。任务完成后,线程使用Synchronize 使用结果更新表单,并且在程序运行时一切正常。

问题发生在线程正在运行并且我关闭程序时出现访问冲突。它是由已经发布的线程更新表单引起的。在重新安排表单创建的顺序(调用Application->CreateForm)后,它工作得很好,因为现在保存线程代码的表单是在更新表单之前创建的。似乎破坏顺序与创建顺序相反。

我还在表单析构函数中添加了一些代码,以确保如果表单在带有线程代码的表单之前被销毁,则线程终止。因此,在表单析构函数中重新排列表单创建顺序和/或代码可以解决问题。

但我有 3 个问题:

  1. 创建的表单被销毁的顺序是什么?是不是和我现在假设的创建顺序相反?

  2. 是否有更好的方法来完成上述任务 - 在线程完成数据处理后更新表单 GUI 项。现在我使用Synchronize从线程本身做这件事,但有线程经验的人可能有更好的主意。我的另一个想法是甚至删除编译器生成的一堆CreateForm 并手动创建它们,仅使用CreateForm 创建主表单以更好地控制破坏顺序(如Rob Kennedy - http://pages.cs.wisc.edu/~rkennedy/createform 所建议)。

  3. 在典型应用程序中动态表单创建/销毁的成本是多少?使用表单隐藏并保存在内存中或关闭时销毁它更好吗?

【问题讨论】:

  • 1) 是的,以相反的顺序销毁 2) 重新发明了轮子。最好重新排列逻辑 3) 取决于您在它们上设计的内容,可能很重。

标签: multithreading delphi user-interface c++builder


【解决方案1】:

当您使用Owner 创建组件时,Owner 会将您的组件添加到它拥有的组件列表中。这发生在这段代码中:

procedure TComponent.Insert(AComponent: TComponent);
begin
  if FComponents = nil then FComponents := TList<TComponent>.Create;
  FComponents.Add(AComponent);
  if FSortedComponents <> nil then
    AddSortedComponent(AComponent);
  AComponent.FOwner := Self;
end;

如您所见,该组件已添加到列表的末尾。

当所有者被销毁时,它会调用DestroyComponents

procedure TComponent.DestroyComponents;
var
  Instance: TComponent;
begin
  FreeAndNil(FSortedComponents);
  while FComponents <> nil do
  begin
    Instance := FComponents.Last;
    if (csFreeNotification in Instance.FComponentState)
      or (FComponentState * [csDesigning, csInline] = [csDesigning, csInline]) then
      RemoveComponent(Instance)
    else
      Remove(Instance);
    Instance.Destroy;
  end;
end;

如您所见,循环首先处理最后一个成员。因此,组件以相反的顺序被销毁。

我个人不会依赖销毁命令。如果表单需要确保在销毁表单之前终止线程,我会在表单的析构函数中编写代码来强制执行。

使用Synchronize 是解决许多问题的完美解决方案。我无法说这是否是解决您问题的最佳方法,因为您还没有完全描述您的问题。

在典型应用程序中动态表单创建/销毁的成本是多少?

不太好。通常,表单是响应用户交互而显示的。程序创建表单的速度比用户处理表单的速度要快得多。所以动态创建表单很少成为问题。如果您想每秒创建和销毁数千个表单,这可能是个问题。但这会很奇怪。

【讨论】:

    猜你喜欢
    • 2016-06-02
    • 2011-09-15
    • 2013-03-02
    • 2017-12-07
    • 1970-01-01
    • 1970-01-01
    • 2016-05-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多