質問: 0) { } } } } } ``` ネストの一番深いifの categoryStatusはComboBoxです。それいがいは全部チェックボックスです。 不思議な事に、例外が発生するのはcategoryStatusのSelectedIndexプロパティを参照しているif文の行なんです。 他のチェックボックスのif文は通過しているようです。 別スレッドからコントロールを参照できないとしたらチェックボックスも参照できないはずではないのですか? なぜComboBoxのみ例外が発生してしまうのでしょうか・・・ ***別スレッドからコントロールのプロパティを参照する方法を教えて下さい。お願いします**。* また、このようにチェックボックスやコンボボックスによって処理を変えたい場合、if文のネストがとてつもない深さになりものすごく見づらいのですが、他にいい方法はありませんか? 追記: すみません。ElementsIndexはDomainUpDownです。 追記: 発生する例外は型 'System.InvalidOperationException'です。 コントロールはすべてメインスレッドで作っています。
回答: BackgroundWorker はバックグラウンド スレッドを作って処理をさせるコンポーネントです。 DoWork はまさにそのためにバックグラウンド スレッド上で実行されるイベントです。 従って(Invoke を介さない限り)DoWork 内でコントロールを操作することはできません。 「何故 ComboBox だけなのか」は「たまたま」です。 MSDN にも書いてあります。 > > DoWork イベント ハンドラーでユーザー インターフェイス オブジェクトを操作しないように注意する必要があります。代わりに、BackgroundWorker のイベントを通じてユーザー インターフェイスと通信します。 > > > ProgressChanged と RunWorkerCompleted はメインスレッド上で呼ばれますのでコントロールを操作することができます。 DoWork 内でも Invoke すればコントロールを操作できますが、Invoke するということはメインスレッドに処理を委譲するということです。 これはバックグラウンド スレッド上で処理するよりも低速です。 BackgroundWorker を使うメリットを殺してしまわないように注意してください。 たとえば、RunWorkerAsync を呼ぶ前にコントロールをすべて Disable にして、そのプロパティを取得しておいて RunWorkerAsync に渡し、DoWork 内ではコントロールのプロパティではなく、渡された値を見て処理をするといった方法が考えられます。 バックグラウンド処理中にもコントロールが随時操作可能であるという仕様であるならば、SelectedIndex を Form のメンバー変数に持たせておいて、SelectedIndexChanged イベントでそれを書き換える、DoWork 内ではメンバー変数の方の SelectedIndex を見るというような方法が考えられます。