C#_別スレッドからコントロールを操作 02

続き。↓前のコピペ。

        private void buttonTest_Click(object sender, EventArgs e)
        {
            // 別スレッドで動かす
            Task.Run( ( ) =>
            {
                for (int i = 0; i < 1001; i++)
                {
                    Hoge(i);
                }
            });
        }
       
        delegate void HogeDelegate(int i);

        private void Hoge(int i)
        {
            if (label1.IsDisposed) return;

            if (label1.InvokeRequired)
            {
                Invoke(new HogeDelegate(Piyo), new object { i });
            }
        }
       
        private void Piyo(int i)
        {
            label1.Text = i.ToString();
        }

 

 HogeDelegate(Hoge) というコード

Invoke ( new HogeDelegate(Piyo), でなく、
Invoke ( new HogeDelegate(Hoge), というコードを使っているサイト多し。

 

Piyo メソッドが消えて else の中に処理が移動。

        delegate void HogeDelegate(int i);

        private void Hoge(int i)
        {
            if (label1.IsDisposed) return;

            if (label1.InvokeRequired)
            {
                Invoke(new HogeDelegate(Hoge), new object { i });
            }
            else
            {
                // コントロールを直接呼び出し
                label1.Text = i.ToString();
            }
        }

↑ コードは、スレッドが異なる場合
コントロールと同一のスレッドで実行されるように、
delegate を使用して Invoke メソッドから呼び出している。

 

new HogeDelegate(Hoge)
同一メソッドへのコールバックを作成している。

 

コールバック
非同期処理の終了のタイミングで何かをしたい場合、
「処理が終わったらこのメソッドを呼んで欲しい」というものを
他スレッド側に渡して呼び出してもらう。
この「他のスレッドで呼び出して欲しいメソッド」がコールバック。
コールバック、スレッド云々は単独で調べないと重い。

 

コールバック関数
この関数をそっちで呼び出して、と関数に引数として渡される関数のこと。

    HogeA ( FugaB )
   
    FugaB()
    {
        // 処理
    }

HogeA も FugaB も関数。
HogeA の中で FugaB の処理が走る。この引数 Fuga B がコールバック関数

 

Invoke ( new HogeDelegate ( Hoge )
親コントロールInvoke メソッドを呼び出すことで
呼び出し元のコントロールスレッドでこのメソッドを実行

 

 

MethodInvoker を用いればデリゲートの定義を省略できる

delegate void HogeDelegate(int i); が不要。

    if (label1.InvokeRequired)
    {
        //Invoke(new HogeDelegate(Hoge), new object[ ] { i });
        Invoke( (MethodInvoker )delegate { Hoge(i); });
    }
    else
    {
        label1.Text = i.ToString();
    }

 

 

こちらから。
http://www.atmarkit.co.jp/ait/articles/0506/17/news111.html
https://so-zou.jp/software/tech/programming/c-sharp/thread/thread-safe-call.htm
http://ultrad2.blogspot.jp/2007/10/invokedelegate.html
http://ufcpp.net/study/csharp/misc_delegate.html
http://wa3.i-3-i.info/word12295.html

 

以上。

下のようなコード書いて、label が順次表示されないっと困ってた
        delegate void HogeDelegate(Label label);

        private void Hoge(Label label)
        {
            Invoke(new HogeDelegate(Piyo), new object[ ] { label });
        }
       
        private void Piyo(Label label)
        {
            for (int i = 0; i < 10001; i++)
            {
                label.Text = i.ToString();
            }
        }
        // メインメソッドで Task.Run( ( ) => Hoge(label1));