Visual Studio で空のWinFormsSTAThread
アプリケーションを作成すると、テンプレートのメイン アプリケーション クラスに属性が含まれます。
私はそれについていくつかのドキュメントを読んでいますが、それをまったく理解しているかどうかはわかりません.
本当に私はそれについていくつか質問があります:
- なぜこの属性が追加されたのですか?
- どういう意味ですか?
- この属性を削除するとどうなりますか?
MSDN ブログから引用するには、
STAThreadAttribute が適用されると、現在のスレッドのアパートメント状態がシングル スレッドに変更されます。COM とスレッド化について大々的に議論するまでもなく、この属性は、現在のスレッドと、COM 経由でスレッドと通信する可能性のある他のスレッドとの間の通信メカニズムを保証します。Windows フォームを使用している場合、使用している機能によっては、オペレーティング システム コンポーネントと通信するために COM 相互運用機能を使用している場合があります。これの良い例は、クリップボードとファイル ダイアログです。
1. なぜこの属性が追加されたのですか?
ActiveX オブジェクト モデルで必要とされるためです。また、ActiveX コントロールを WinForm にドロップすることもできます (互換性のために存在します)。または、一部の .NET クラスは、その属性を必要とするネイティブ コントロールを使用します。
2. どういう意味ですか?
これは、スレッドがシングルスレッド アパートメント モデルで実行されることを意味します。
3. この属性を削除するとどうなりますか?
属性が削除された場合、動作は未定義です。プログラムはランダムに失敗する場合があり、場合によっては適切なエラー メッセージが表示されます。たとえば、現在は機能していても、サービス パックで機能しなくなる場合があります。
3.この属性を削除するとどうなりますか?
問題を示す簡単な例を追加するだけです。
ボタンと OpenFileDialog を備えたシンプルな WinForms アプリを作成しました。ボタンをクリックすると、openFileDialog を示すスレッドが実行されます。STAThread の有無にかかわらずアプリを起動し、ボタンをクリックした結果は同じです。「クロススレッド操作が無効です: コントロール 'Form1' が作成されたスレッド以外のスレッドからアクセスされました」という例外がスローされます。まるで違いがないように見えます。しかし、いいえ。
次に、以下のメソッドを呼び出して openFileDialog の表示を変更しました。
private void ShowOFD()
{
if (InvokeRequired)
{
BeginInvoke(new Action(ShowOFD));
return;
}
openFileDialog1.ShowDialog(this);
}
STAThread を使用すると、期待どおりに正常に動作します。STAThread がないと、例外がスローされます。「OLE 呼び出しを行う前に、現在のスレッドをシングル スレッド アパートメント (STA) モードに設定する必要があります。Main 関数に STAThreadAttribute がマークされていることを確認してください。この例外は、デバッガーが接続されている場合にのみ発生します。プロセス"。
次に、デバッガーを使用せずにアプリを数回起動します (ビジュアル スタジオから切り離されます)。あるときはアプリが静かに閉じられ、別のときは「vshost has stopped working」というメッセージが表示されてアプリが閉じられました
これは、Windows フォーム プログラムがシングル スレッドのアパートメント状態を使用することを意味します。MTA およびフリー スレッド アパートメント状態はサポートされていません。