0

BackgroundWorker スレッドを実行するメイン フォームがあります。ワーカーが実行されている間、メイン フォームを「フリーズ」し、進行状況を表示しながら終了するのを待ちます。

シナリオの 1 つでは、ワーカーはユーザーがファイルを選択できるように OpenFileDialog を表示できます。3 番目のスレッドを使用して OpenFileDialog を実行し、ApartmentState を STA に設定します。これは、OpenFileDialog がそれを要求し (実行しないと例外がスローされます)、ワーカーの ApartmentState が MTA であるためです。

問題は、OpenFileDialog.ShowDialog を呼び出すときに使用できるように、メイン フォームをパラメータとして OpenFileDialog スレッドに渡したいことです。このようなもの:

public void ThreadProcShowDialog(object param)
{
    Form parent = (Form)param;
    dialog.ShowDialog(parent);
}

もちろん、ShowDialog は次をスローします。

クロススレッド操作が無効です: コントロール 'Form' は、それが作成されたスレッド以外のスレッドからアクセスされました。

スレッドセーフな方法でこれを行うにはどうすればよいですか?

これの目的は、OpenFileDialog が STA スレッドで実行され、メイン フォームがその上に表示されないようにすることです (ユーザーが下のフォームをクリックするのをブロックして、OpenFileDialog を非表示にします)。

ありがとう

4

1 に答える 1

2

それを見つけた!

私と一緒に働いている仲間のプログラマーは、実際に機能する簡単な解決策を提案しました。3 番目のスレッドで OpenFileDialog を実行する代わりに、メイン フォーム (ワーカー スレッドを開始したフォーム) で実行します。

次のようになります。

//Code inside worker method
OpenFileDialog dialog= new OpenFileDialog();
DialogResult result = DialogResult.None;

Invoke(new MethodInvoker(delegate() { result = dialog.ShowDialog(this); }));
if (result == DialogResult.OK)
{
    ...
}

このようにして、メイン フォームがクリックされないようにブロックし、OpenFileDialog を STA スレッドで実行します。

そして、それを解決したのは C++ プログラマーだと思います。;-)

これが誰かの役に立てば幸いです...

于 2012-01-11T06:17:57.160 に答える