0

このフォームを更新するために特定のフォームの関数を呼び出すスレッドがあります。タスクが完了すると、スレッドは結果を使用してフォームを更新Synchronizeし、プログラムの実行中にすべて正常に機能します。

スレッドが実行されているときに問題が発生し、アクセス違反が発生したプログラムを閉じます。既にリリースされているスレッド更新フォームが原因でした。フォーム作成 ( への呼び出しApplication->CreateForm) の順序を並べ替えた後、フォームが更新される前にスレッド コードを保持するフォームが作成されるようになったため、正常に機能しました。破壊の順序は創造の順序と逆のようです。

また、フォーム デストラクタにいくつかのコードを追加して、フォームがスレッド コードでフォームの前に破棄された場合にスレッドが終了するようにしました。そのため、フォームの作成順序やフォーム デストラクタのコードを並べ替えると、問題が解決します。

しかし、私は3つの質問があります:

  1. 作成されたフォームが破棄される順序は? 今想定している作成順序の逆ですか?

  2. 上記のタスクを実行するためのより良い方法はありますか - スレッドがデータの処理を完了した後にフォーム GUI アイテムを更新します。現在、私はスレッド自体を使用してそれを行っていますSynchronizeが、スレッドの経験がある人はより良いアイデアを持っているかもしれません. CreateForm私が持っていたもう1つのアイデアは、コンパイラーによって生成された束を削除して手動で作成しCreateForm、破壊の順序をより適切に制御するために使用するメインフォームのみを作成することでした(Rob Kennedyが提案したように- http://pages.cs.wisc.edu/ ~rkennedy/createform )。

  3. 一般的なアプリケーションでの動的フォームの作成/破棄のコストはどれくらいですか? フォーム非表示を使用してメモリに保持するか、閉じるときに破棄する方が良いですか?

4

1 に答える 1

3

を使用してコンポーネントを作成すると、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ことは、多くの問題に対する完全に立派な解決策です。あなたの問題を完全に説明していないため、それがあなたの問題に対する最善の解決策であるかどうかは、私には言えません。

一般的なアプリケーションでの動的フォームの作成/破棄のコストはどれくらいですか?

あまりない。通常、フォームはユーザーの操作に応じて表示されます。プログラムは、ユーザーがフォームを処理するよりもはるかに速くフォームを作成できます。そのため、動的にフォームを作成しても問題になることはほとんどありません。1 秒間に何千ものフォームを作成および破棄したい場合、これは問題になる可能性があります。しかし、それは奇妙でしょう。

于 2013-05-04T18:25:25.847 に答える