Delegate為委派,Invoke表示要呼叫所指定的方法(method),第二個為傳入參數陣列
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: }
參考資料
1. https://msdn.microsoft.com/zh-tw/library/a1hetckb(v=vs.110).aspx