私は(クロススレッド例外を取得する)私が取り組んでいる大きなアプリケーションでいくつかのスレッド問題があります。特定のコントロールが作成されたスレッド名/ idを見つける方法はありますか?コントロールのオーナースレッドを見つける方法はありますか?
コントロールのコントロールコレクションに新しいコントロールを追加しようとするとエラーが発生します。私は実際に小さな、再現可能なサンプルを作成することはできませんので、私ができる限りそれを説明します。
私はフォーム上に座っているメインコントロールを持っています、それを_mainControlと呼んでください。そのコンストラクタでは、私は別のコントロールのインスタンスをインスタンス化し、
ChildControl _childControl = new ChildControl();
のようなものは今_childControlが存在しますが、私はまだ_mainControlsコレクションに追加しないでください。
最終的に_mainControlはコントロールを追加する必要があるというイベント通知を受け取ります。イベントハンドラではthis.InvokeRequired場合、私はチェックして、それがある場合、私は、次のようなものをハンドラを起動します。
AddControlEventHander(...)
{
if(InvokeRequired)
{
BeginInvoke(new MethodInvoker(AddControlEventHander);
return;
}
Controls.Add(_childControl);
}
例外は常にControls.Add(有効ではありません "クロススレッド動作時にスローされます。コントロール '_item'は、作成されたスレッド以外のスレッドからアクセスされます)。
今、私は理解できないことは、これがどういうことかということです。 _mainControlが作成されたのと同じスレッドで_childControlを作成しました。デバッグ中にスレッドウィンドウを見ると、_childControlが追加されたときと同じようにControl.Addを呼び出すと、現在のスレッド名/ IDが同じになります。しかし、私を最も混乱させるものは、_mainControlからの以下の呼び出しです。
InvokeReuqired == false;
_childControl.InvokeRequired == false;
_childControl._item.InvokeRequired == true; //I made _item public just to try this and it returns true!
これはどのように可能ですか? _childControlは、その子が別のスレッドで何らかの形で作成されている間に1つのスレッドで作成することは可能ですか? _childControlのすべての子は、通常行われるように、初期化中に作成されます。
何が起こっているのかについてのヒントや提案がありましたら、お知らせください。
ありがとうございました。
編集:誰もが興味を持っている
場合は、私が起こっていたことが分かりました。 1つのスレッドでコントロールを作成する方法と、同じスレッドでInitializeComponentがすべて実行されたにもかかわらず、別のスレッドで作成された子が好きです。そこで、チャールズが以下に示唆したのと同様のコードを使って、子供が作成されたスレッドを見つけました。私がそれを知ったら、少なくとも、どのスレッドに集中すべきかを知っていました。次に、子コントロールのOnHandleCreatedイベントを壊して問題を発見しました。
私が知らなかったことは、コントロールが初めて作成されたときにコントロールが表示されたときにコントロールのハンドルが作成されることでした。したがって、コントロールを所有していないスレッドは、可視性をtrueに設定しようとしていました。だから私はInvokeRequiredとそれがトリックを行うだろうと思ったかどうかを確認するためのチェックを追加しました。しかし、私が実際には期待していなかったことは、まだ作成されていない場合、InvokeRequiredを呼び出すとコントロールのハンドルが作成されるということです!これにより、実際には間違ったスレッドでコントロールが作成され、常にInvokeRequiredに対してfalseが返されます。コントロールのHandleプロパティに触れ、InvokeRequiredが呼び出される前にコントロールが作成されるようにして、この問題を回避しました。ヘルプみんなのため
感謝:)
ヒントをお寄せいただきありがとうございます。同様に無害な 'if(control.Handle!= null)...'が実際にそのスレッドのコントロールを作成することも発見しました! –
ここに私の答えを見なさいhttp://stackoverflow.com/questions/8331144/ensuring-that-child-controls-are-created-in-main-ui-thread/17054689#17054689 –