2013年6月22日 星期六

[C#.NET] 委派

參考文章:
msdn ThreadStart 委派
[C#.NET] 如何 使用 多執行緒 Thread / 跨執行緒 存取UI
[C#]執行緒(Thread)使用與執行緒上操作UI

最近在巨匠上邱老師的.net課程, 提到Thread與委派, 是初學者容易"卡關"的地方, 
在這, 就以初學者的角度寫一篇分享:
        //先"委派"一個thread_callback的函式
        private delegate void thread_callback(string data);

        //"非同步呼叫"函式setAnswer,求data (即傳遞參數給多執行緒)
        private void setAnswer(string data)
        {
            if (this.InvokeRequired)
            {
                thread_callback cc = new thread_callback(setAnswer);
                this.Invoke(cc, data);
            }
            else
            {
                this.textbox.Text = data;
            }
        }

以上是通用型式,以下補充上課的範例
做2個按紐,上面那個將label1.text每次加1
                    下面那個用Thread的方法來達到"分時多工"的目的

程式碼:

using System;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
// 執行緒的建立,其實也是一種委派,讓開發者省略"public delegate void ThreadStart()"等程式碼



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

        private void button1_Click(object sender, EventArgs e)
        {
            label1.Text = (int.Parse(label1.Text) + 1).ToString();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            ThreadStart ts = new ThreadStart(MyThreadRun);
            Thread tt = new Thread(ts);
            tt.Start();
        }

        private void MyThreadRun()
        {
            long sum = 0;
            for (long i = 1; i <= 2000000000; i++)
            {
                sum += i;
            }
            setAnswer(sum);      
        }

        //宣告委派方法
        private delegate void thread_callback(long ans);

        //非同步呼叫完成後的方法的實體
        private void setAnswer(long a)
        {
            if (this.label2.InvokeRequired)
// 本例中,因為是Label2.Text要用,所以和文章開頭的範例略有不同;

            {
                thread_callback cc = new thread_callback(setAnswer);
// 這邊就是利用委派來呼叫setAnswer這個函式,
                this.Invoke(cc, a);
            }
            else
            {
                label2.Text = "答案:" + a;
            }
        }
    }
}
// ok結束啦, let's call it a day

沒有留言: