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

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

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

Re[5]: 他クラスのスレッドからのフォームコントロール


(過去ログ 87 を表示中)

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

■51743 / inTopicNo.1)  他クラスのスレッドからのフォームコントロール
  
□投稿者/ jane (1回)-(2010/07/15(Thu) 16:49:05)

分類:[.NET 全般] 

失礼します。どうしてもわからないので質問させていただきます。

現在、あるライブラリを作っています。
そのライブラリ(クラス)は新しいスレッドを持っておりそのスレッドの中で文字列が引数のイベントが起こされます。

そのイベントをライブラリを使用しているフォームで処理したいのですが、フォーム側で引数を触ろうとすると
「有効ではないスレッド間の操作」となってしまい、処理することができません。
どのようにすればいいのでしょうか?

デリゲートとinvokeを使うのかとか考えたのですがよく分かりませんでした。
どなたかわかるからがいらっしゃいましたらご教授ください。よろしくお願いいたします。


同じことを再現したサンプルソースを載せておきます。

[Form1側]

        Class1 testclass = new Class1();

        private void Form1_Load(object sender, EventArgs e)
        {
            //Class1にイベントを起こしてもらう
            testclass.testevent += new Class1.testdelegate(testclass_testevent);
            testclass.Event();
        }

        void testclass_testevent(string str)
        {
            //cぁss1で起こされたイベント
            //イベントの引数をフォームのタイトルに表示する
            //ここでエラー
            this.Text = str;
        }

[class1側]

        //イベントの作成
        public delegate void testdelegate(string str);
        public event testdelegate testevent;

        public void Event()
        {
            //新しいスレッドを作成
            System.Threading.Thread testthread = new System.Threading.Thread(thread);
            testthread.Start();
        }

        private void thread()
        {
            //新しいスレッド内でイベントを起こす
            //これでフォームのタイトルにテストですと表示されてほしい
            testevent("テストです");
        }

引用返信 編集キー/
■51745 / inTopicNo.2)  Re[1]: 他クラスのスレッドからのフォームコントロール
□投稿者/ aetos (318回)-(2010/07/15(Thu) 17:44:00)
No51743 (jane さん) に返信

コントロールを作ったのと違うスレッドでコントロールのプロパティやメソッドにアクセスしてはなりません。
違うスレッドから呼び出していいメソッドは Invoke、BeginInvoke、EndInvoke、CreateGraphics の4つだけです。

>         void testclass_testevent(string str)
>         {
>             //cぁss1で起こされたイベント
>             //イベントの引数をフォームのタイトルに表示する
>             //ここでエラー
>             this.Text = str;
>         }

if (InvokeRequired)
{
    Invoke((Action) (() => Text = str));
}
else
{
    Text = str;
}

とでもすればよろしいかと。

引用返信 編集キー/
■51746 / inTopicNo.3)  Re[2]: 他クラスのスレッドからのフォームコントロール
□投稿者/ jane (2回)-(2010/07/15(Thu) 18:27:25)
No51745 (aetos さん) に返信
> ■No51743 (jane さん) に返信
>
> コントロールを作ったのと違うスレッドでコントロールのプロパティやメソッドにアクセスしてはなりません。
> 違うスレッドから呼び出していいメソッドは Invoke、BeginInvoke、EndInvoke、CreateGraphics の4つだけです。
>
>> void testclass_testevent(string str)
>> {
>> //cぁss1で起こされたイベント
>> //イベントの引数をフォームのタイトルに表示する
>> //ここでエラー
>> this.Text = str;
>> }
>
> if (InvokeRequired)
> {
> Invoke((Action) (() => Text = str));
> }
> else
> {
> Text = str;
> }
>
> とでもすればよろしいかと。


お返事ありがとうございます!
一応処理することができました!
しかし欲を言えばライブラリですのでなるべくフォーム側でそのようなことを書きたくありません、別クラスのほうはどうなってもいいので別クラス内で処理をして
フォーム側はthis.Text = str;だけで済ませることは不可能でしょうか?
引用返信 編集キー/
■51747 / inTopicNo.4)  Re[3]: 他クラスのスレッドからのフォームコントロール
□投稿者/ todo (25回)-(2010/07/15(Thu) 19:08:52)
class1にフォームのインスタンスを渡す。
http://www.ipentec.com/document/document.aspx?page=csharp-update-form-control-from-subthread

引用返信 編集キー/
■51749 / inTopicNo.5)  Re[4]: 他クラスのスレッドからのフォームコントロール
□投稿者/ なちゃ (459回)-(2010/07/15(Thu) 20:04:15)
昔ながらのやり方ならISynchronizeInvoke辺りを、
新しいやり方ならAsyncOperationManager辺りを調べてみてください。

引用返信 編集キー/
■51750 / inTopicNo.6)  Re[5]: 他クラスのスレッドからのフォームコントロール
□投稿者/ jane (3回)-(2010/07/15(Thu) 20:16:41)
みなさんありがとうございます!
クラスなのでコントロールがなくてinvokeできないならコントロールを渡してやればよかったんですね、盲点でした。
とりあえずこれで満足いたしました。
今からAsyncOperationManagerについても調べてみたいと思います。ありがとうございました!
解決済み
引用返信 編集キー/


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

このトピックに書きこむ

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

管理者用

- Child Tree -