close

Delegate為委派,Invoke表示要呼叫所指定的方法(method),第二個為傳入參數陣列

image

MyFormControl繼承Form

1. Line 3: 宣告委派:delegate void AddListItem(String myString),表示需要傳入一字串無回傳值。

2. Line4: 宣告委派:delegate void ClearListItem(),表示無參數輸入且無回傳值。

3. Line5~6: myAddDelegate和myClearDelegate則為上述兩種委派的物件,目前未實體化。

4. MyFormControl創建子 MyFormControl(){…} 主要在視窗建立myButton和myListBox,利用Controls.AddRange加入控制元件。

5. Line 26: 實體化myAddDelegate委派物件,傳入參數為AddListItemMethod方法名稱,該方法符合委派方法樣板定義(Line 3)。

6. Line 27: 實體化myClearDelegate委派物件,傳入參數為ClearListItemMethod方法名稱,該方法符合委派方法樣板定義(Line 4)。

7. Line 29: 按鈕事件: 執行執行緒ThreadFunction

8. Line 42: 執行緒ThreadFunction方法: 實體化一個MyThreadClass物件,同時將目前MyControlForm物件本身當作引數傳入,接著直接執行myThreadClassObject.Run()方法。

   1: public class MyFormControl:Form
   2:    {
   3:        public delegate void AddListItem(String myString);
   4:        public delegate void ClearListItem();
   5:        public AddListItem myAddDelegate;
   6:        public ClearListItem myClearDelegate;
   7:        private Button myButton;
   8:        private Thread myThread;
   9:        private ListBox myListBox;
  10:        public MyFormControl()
  11:        {
  12:            myButton = new Button();
  13:            myListBox = new ListBox();
  14:            myButton.Location = new Point(72, 160);
  15:            myButton.Size = new Size(152, 32);
  16:            myButton.TabIndex = 1;
  17:            myButton.Text = "Add items in list box";
  18:            myButton.Click += new EventHandler(Button_Click);
  19:            myListBox.Location = new Point(48, 32);
  20:            myListBox.Name = "myListBox";
  21:            myListBox.Size = new Size(200, 95);
  22:            myListBox.TabIndex = 2;
  23:            ClientSize = new Size(292, 273);
  24:            Controls.AddRange(new Control[] { myListBox, myButton });
  25:            Text = " 'Control_Invoke' example ";
  26:            myAddDelegate = new AddListItem(AddListItemMethod);
  27:            myClearDelegate = new ClearListItem(ClearListItemMethod);
  28:        }
  29:        private void Button_Click(object sender, EventArgs e)
  30:        {
  31:            myThread = new Thread(new ThreadStart(ThreadFunction));
  32:            myThread.Start();
  33:        }
  34:        private void AddListItemMethod(String myString)
  35:        {
  36:            myListBox.Items.Add(myString);
  37:        }
  38:        private void ClearListItemMethod()
  39:        {
  40:            myListBox.Items.Clear();
  41:        }
  42:        private void ThreadFunction()
  43:        {
  44:            MyThreadClass myThreadClassObject = new MyThreadClass(this);
  45:            myThreadClassObject.Run();
  46:        }
  47:    }

1. MyThreadClass類別中包含一個myFormControl1,這個物件會在MyThreadClass創建子階段(Line 4~7), 由上面一段程式中Line 44傳入this被初始化。

2. if(myFormControl1.InvokeRequired) 判斷目前被呼叫的程式是否屬於相同執行緒,若不同則InvokeRequired為真。

3. 由於ThreadFunction是屬於另外一隻執行緒,與控制元件分屬不同執行緒,因此呼叫必須採用myFormControl1.Invoke(…)方式呼叫,Invoke()參數為委派實體物件,Line15 為myFormControl1.myClearDelegate委派實體

4. Line 21~36 為列印字串 myString,該字串動態變化 “Step number” + i.ToString() + “ executed;

5. 和第3點狀況相同,由於ThreadFunction是屬於另外一隻執行緒,與控制元件分屬不同執行緒,因此呼叫必須採用myFormControl1.Invoke(…)方式呼叫,Invoke()參數為委派實體物件,Line29 為myFormControl1.myAddDelegate委派實體,該委派需同時傳入一組字串,在此以new object[]物件陣列方式傳入

   1: public class MyThreadClass
   2:    {
   3:        MyFormControl myFormControl1;
   4:        public MyThreadClass(MyFormControl myForm)
   5:        {
   6:            myFormControl1 = myForm;
   7:        }
   8:        String myString;
   9:        public void Run()
  10:        {
  11:            if(myFormControl1.InvokeRequired)
  12:            {
  13:                MessageBox.Show("myFormControl1.InvokeRequired");
  14:                // invoke 無參數傳入
  15:                myFormControl1.Invoke(myFormControl1.myClearDelegate);
  16:            }
  17:            else
  18:            {
  19:                myFormControl1.myClearDelegate();
  20:            }
  21:            for (int i = 1; i <= 5; i++)
  22:            {
  23:                myString = "Step number " + i.ToString() + " executed";
  24:                Thread.Sleep(400);
  25:                // Invoke 1參數傳入
  26:                if (myFormControl1.InvokeRequired)
  27:                {
  28:                    //MessageBox.Show("myFormControl1.InvokeRequired");
  29:                    myFormControl1.Invoke(myFormControl1.myAddDelegate, new object[] { myString });
  30:                }
  31:                else
  32:                {
  33:                    myFormControl1.myAddDelegate(myString);
  34:                }
  35:            }
  36:        }
  37:    }

 

 image

image

 

 

參考資料

1. https://msdn.microsoft.com/zh-tw/library/a1hetckb(v=vs.110).aspx

全站熱搜
創作者介紹
創作者 me1237guy 的頭像
me1237guy

天天向上

me1237guy 發表在 痞客邦 留言(0) 人氣()