2011-10-18 10 views
2

すべて:不正なクロススレッディング*が検出されないのはなぜですか?

私はWindowsフォームとボタンを作成しました。別のスレッドでは、ボタンのテキストを変更しようとしましたが、クラッシュします。ボタンの色を変更しようとすると、確実に成功します。私はあなたがWindowsフォームコントロールのプロパティを変更した場合、クラッシュすると思っていました。誰かが何が起こっているか教えていただけますか?

はここでコメントアウト行にクラッシュしていない私のコードです(しかし、私はそれが必要と思った):

Thread thr = new Thread(() => { 
    //myButton.ForeColor = Color.Purple; // this never causes a crash :=(
    myButton.Text = Color.Purple.ToString(); // this always causes a crash. 
}); // 
thr.Start(); 

任意の洞察力をいただければ幸いです!

マイケル

答えて

6

Control.ForeColorプロパティ設定ツールは、Invalidate()メソッドを呼び出します。 Windowsではスレッドセーフです。これは単に、内部ウィンドウ状態の "このウィンドウを再描画する必要があります"ステータスビットを設定します。ペイントイベントが実行されるまでは、実際にはウィンドウが表示されません。 UIスレッド上。

Winformsには、例外を抑制する明示的なコードが含まれています。

他の例では、Textプロパティを読み込んでいます(書き込みではありません)。そして、文書化されたもの、InvokeRequired、BeginInvoke、EndInvoke、Invoke、およびCreateGraphics。それでおしまい。

+0

説明をありがとう。レコードのために、Microsoftのドキュメントではあいまいさが許されません。「デバッガでアプリケーションを実行していて、コントロールを作成したスレッド以外のスレッドがそのコントロールを呼び出そうとすると、デバッガはInvalidOperationExceptionを発生させます"私は彼らがもっと細かい詳細を提供してくれたらと思っています... –

+0

ドキュメンテーションが完璧だったら、StackOverflowのようなサイトは必要ありません:)それは98%正確です。 –

+0

学問的興味のために、あなたは石炭の顔での個人的な経験から見つけたか、あなた自身で調査しましたか(もしそうならば)、あるいはどこかで実際に文書化されていますか? – tomfanning

0

確実

が遠すぎるあなたの運をプッシュしないでください成功しました。遅かれ早かれそれはクラッシュするでしょう。常にGUIスレッドの変更を実行します。

+0

おそらくあなたは正しいですが、_often_ ForeColorがエラーなしで設定されていることは本当に驚きです。どうして?それはUIの変更ではありませんか?デバッグ中にメインスレッドで実行すべきではありませんか? – Marco

+1

@Marco:クライアントのコンピュータ上で、たとえばセキュリティパッチの後で動作が変更される可能性があります - それがドキュメント化されていない場合を除きます。 – Vlad

0

Documentationは言う:

Invokeメソッドを使用せずにコントロールを作成したもの以外のスレッドからコントロールを呼び出すために安全ではありません。

最初に目を通さずに通りを横切るのは安全ではありません。あなたはいつも車にぶつかることはありませんが、あなたのチャンスはかなり高いです。

この例外は、デバッグ中、および場合によっては実行時に確実に発生します。 .NET Framework Version 2.0より前の.NET Frameworkで作成したアプリケーションをデバッグすると、この例外が表示されることがあります。この問題は表示されたときに修正することを強くお勧めしますが、CheckForIllegalCrossThreadCallsプロパティをfalseに設定することで無効にすることができます。

関連する問題