2010-12-07 3 views
4

以前は、そのコントロール用にハンドルが作成される前にUIスレッドで呼び出しをマーシャリングするためにControlが使用された結果、フリーズの問題が発生しました。 (詳細はKim Greenlee's blogを参照してください)。作成されたすべてのコントロールに.NETでハンドルがあることを確認することの副作用は何ですか?

このメソッドを使用すると、再帰的に実装されます。アプリケーションで作成されたすべてのコントロールが、作成時にハンドルされるようにします。具体的には、これはデザイナの呼び出しの後に行われ、コントロールのGUIを初期化します。

私の質問は:

Q - 別にパフォーマンスから、すべてのコントロールは、このようにハンドルを持っていることを確認しない他の理由があるのですか?

Infragistics Panelの内部にInfragisticsコントロールが配置されているため、問題が発生しているようです。ユーザーがこのパネルのサイズを変更すると、DockプロパティがDock.Fillに設定されていても、含まれているInfragisticsコントロールのサイズが正しく変更されません。このコントロールに表示されるツールチップがマウスの隣に表示されなくなる問題もあります。これらの問題は、コンテナとコントロールを含むコントロールの両方で、自分自身とすべての子コントロール用にハンドルが作成されていることを確認できない場合に解決されます。

ここに誰かが私の質問に答えることができれば幸いです。ブローニーは、なぜ私はこの問題も見ているかもしれない理由をいくつか明かすことができる誰のためのポイント! =)しかし、私はこの質問がInfragisticsチームの方が多いと思います。

乾杯!

+0

あなたはそうです、これをInfragisticsサポートフォーラムに投稿してください。 –

+1

問題自体はそうです。しかし、誰かがハンドルの作成を強制することに関する情報を持っているかどうかを知りたいのですが、これをやっていない理由は分かりません。私はこれが、ここの誰もが私を助けてくれる一般的な質問だと感じました(ここでの回答はInfragisticsフォーラムではなく、より迅速で詳細で簡潔です)。私は今でもInfragisticsに質問を投稿しました。しかし、応答ありがとう、ハンス=)。 – Roo

+1

ウィンドウハンドルの主な問題は、それらがグローバルに限られたリソースだということです。 Win2000以降では、1アプリケーションあたり10k、合計64k(1台のデスクトップあたり)と思います。 – CodesInChaos

答えて

0

さて、私は特定の問題を解決しました。これはInfragisticsコンポーネントの問題ではありませんでした。私は単に間違った時刻にハンドルの作成を強制していました...

私は、各カスタムコントロール/フォームの構築で、InitializeComponent()コールの後にハンドルを作成していました。これはフォームでは問題ありませんが、この段階でコントロールは親コントロール/フォームに配置されていない可能性が非常に高いです。コントロールに親を持たせていないときにハンドルの作成を強制するのは明らかに悪いことです。

だから私は、これを実現するために親指の私のルールを変更しました:すべての子コントロールが、フォーム自体とその子コントロールのために、追加された後、フォームについて

  • ハンドルの力の作成を。私は通常、InitializeComponent()の呼び出しの後にフォームのコンストラクトでこれを続けます。
  • コントロールの場合、新しいコントロールとそのすべての子コントロール(存在する場合)に対して、コントロールが作成されてその親のContol/Formに追加された後にハンドルを強制的に作成します。

この機能を正しく使用することを確実にすると、唯一の欠点は潜在的なパフォーマンスの問題です(これは私が本当に正直では気づいていない)。

私は、この機能を使用することについての正式な説明と、親コントロールに配置される前にコントロールのハンドルの作成を強制する方法の技術的な説明を歓迎します。ビットの短い...

Rooの

1

あなたがあなた自身のコードにマーシャリングするか、それはいくつかの外部のコードで発生した一方で、これらの問題を持っていましたか?

私はこれらの問題も数回持ち、SynchronizationContextクラスを使用して切り替えました。このクラスのための明確なプロはあなたがスレッド間のマーシャリングのためのコントロールを必要としないということです。

あなたはこのようなあなたが呼ばれるようにしたいスレッド(つまり、UIスレッド)上のクラスのインスタンスを取得する必要があります。

private SynchronizationContext m_oSyncContext = SynchronizationContext.Current ?? new SynchronizationContext(); 

このインスタンスを使用して、あなたがどんなからの投稿/送信メソッドを使用することができますスレッドは、(a)そのインスタンスが取り出されたスレッドにメッセージを同期的に送信する。

この問題を解決するには、正しいスレッドでインスタンスを取得する必要があります。私は上記のサンプルのようにすることをお勧めします。インスタンスがすでに存在している間にインスタンスを作成すると、いくつかの厄介な副作用が発生する可能性があります。

+0

うわー!提案していただきありがとうございます。私はこのクラスについて聞いたこともないだろうが、これを読んだ後:http://www.codeproject.com/KB/threads/SynchronizationContext.aspxそれはもっときれいで、きれいに見える!私たちのアプリケーションは非常に大きく、そのようなマーシャルは多くの場所を呼び出すので、これはかなり変更する作業ですが、私は確かにこれを頭に入れて将来を考えます。ありがとう! – Roo