C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[4]: 他スレッドで起動した画面でDialogが使用できない


(過去ログ 52 を表示中)

[トピック内 5 記事 (1 - 5 表示)]  << 0 >>

■28622 / inTopicNo.1)  他スレッドで起動した画面でDialogが使用できない
  
□投稿者/ ayane (1回)-(2008/11/28(Fri) 11:08:40)

分類:[VB.NET/VB2005 以降] 

[開発環境]WinXP/VS2005/.NET C#/Framework2.0

はじめまして。

現在、C#で開発を行っており、メイン画面からサブ画面を別スレッドで起動しています。

サブ画面にOpenFileDialogがある場合にダイアログを開こうとすると以下のようなエラーが表示されます。
●エラー内容:
「OLE が呼び出される前に、現在のスレッドが Single Thread Apartment (STA) モードに設定されていなければなりません。
 Main 関数に STAThreadAttribute が設定されていることを確認してください。 
 この例外はデバッガがプロセスにアタッチされている場合にのみ発生します。」

Main関数には、[STAThread]が記述されており、試しにメイン画面にOpenFileDialogを追加してダイアログを開くと
正常にダイアログが表示されます。

サブ画面が別スレッドで起動されているのが原因だと思うのですが、この現象は回避できるのでしょうか?
知っておられる方がおりましたら、ぜひ教えていただけないでしょうか?
よろしくお願いします。

サンプルソースです。

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        //
        // button1イベント(別スレッドで画面を起動する)
        //
        private void button1_Click(object sender, EventArgs e)
        {
            ThreadShowForm();
        }

        //
        // 別スレッドでサブフォームを起動する
        //
        private void ThreadShowForm()
        {
            try
            {
                Thread thread = new Thread(new ParameterizedThreadStart(StartKinouThread));
                thread.Start(thread);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Source + " :\n " + ex.Message);
            }

        }

        public void StartKinouThread(object thread)
        {
            try
            {
                ShowForm();
                Thread currentThread = thread as Thread;

                // 画面閉じた処理
                // スレッド中止
                if (currentThread != null)
                {
                    if (currentThread.ThreadState != System.Threading.ThreadState.Aborted)
                    {
                        currentThread.Abort();
                    }
                }
            }
            catch (ThreadAbortException)
            {
                Thread.ResetAbort();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Source + " :\n " + ex.Message);
            }
        }

        //
        // サブフォームの起動
        //
        private void ShowForm()
        {
            Form2 frm = new Form2();
            frm.Text = frm.Handle.ToString();
            frm.ShowDialog();
        }

        //
        // メインフォーム側のダイアログ表示(正常に表示される)
        //
        private void button3_Click(object sender, EventArgs e)
        {
            this.openFileDialog1.ShowDialog();
            MessageBox.Show(this.openFileDialog1.FileName);
        }

    }

    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }

        //
        // サブフォーム側のダイアログ表示(エラーになる)
        //
        private void button2_Click(object sender, EventArgs e)
        {
            this.openFileDialog1.ShowDialog();
            MessageBox.Show(this.openFileDialog1.FileName);

        }
    }

引用返信 編集キー/
■28625 / inTopicNo.2)  Re[1]: 他スレッドで起動した画面でDialogが使用できない
□投稿者/ 渋木宏明(ひどり) (964回)-(2008/11/28(Fri) 11:26:33)
渋木宏明(ひどり) さんの Web サイト
> サブ画面が別スレッドで起動されているのが原因だと思うのですが、この現象は回避できるのでしょうか?

サブ画面を開くスレッドを STA にしてあげればいいんじゃないでしょうか。

ですが、それ以前の話として、僕は今までに「Windows Forms はプライマリスレッド以外でも万全に動作する」という資料を見かけた記憶がありません。

引用返信 編集キー/
■28630 / inTopicNo.3)  Re[2]: 他スレッドで起動した画面でDialogが使用できない
□投稿者/ ayane (2回)-(2008/11/28(Fri) 12:47:01)
No28625 (渋木宏明(ひどり) さん) に返信
渋木宏明(ひどり)さま。返信ありがとうございました。

> サブ画面を開くスレッドを STA にしてあげればいいんじゃないでしょうか。
サブ画面を開くスレッドを STA にするというのは、
[STAThread] の記述をどこかに追加するということではないんですよね。
完全に的外れな事を言っているのは承知なのですが、正直どのような変更
すればいいのか分かりませんでした。

> ですが、それ以前の話として、僕は今までに「Windows Forms はプライマリスレッド以外でも万全に動作する」という資料を見かけた記憶がありません。
という事は、フォームを使用して作成している画面(DLL)を起動するときも
一緒なんですね・・・

現在、C#で作成されているシステムがメイン画面から各プログラム(DLL)を
起動していて、今回起動の仕方を別スレッドで起動するような変更依頼があり
色々調査している最中です。
ある程度は実行できたのですが、今回の質問で行ったDialogやスレッド間での
やり取りなど修正箇所がたくさんある中で確実にこうすれば動きますという
情報が少なく調査する時間も限られているので別の手法も含め再検討してみたいと思います。

引用返信 編集キー/
■28638 / inTopicNo.4)  Re[3]: 他スレッドで起動した画面でDialogが使用できない
□投稿者/ 渋木宏明(ひどり) (965回)-(2008/11/28(Fri) 13:21:45)
渋木宏明(ひどり) さんの Web サイト
> [STAThread] の記述をどこかに追加するということではないんですよね。
> 完全に的外れな事を言っているのは承知なのですが、正直どのような変更
> すればいいのか分かりませんでした。

ヘルプ等で Thread.SetApartmentState() メソッドについて調べてみてください。

引用返信 編集キー/
■28642 / inTopicNo.5)  Re[4]: 他スレッドで起動した画面でDialogが使用できない
□投稿者/ ayane (3回)-(2008/11/28(Fri) 13:34:52)
No28638 (渋木宏明(ひどり) さん) に返信
>>[STAThread] の記述をどこかに追加するということではないんですよね。
>>完全に的外れな事を言っているのは承知なのですが、正直どのような変更
>>すればいいのか分かりませんでした。
>
> ヘルプ等で Thread.SetApartmentState() メソッドについて調べてみてください。

調べてみて、ロジックの中に組み込んで実行したところ、うまくいきました。
本当にありがとうございました。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -