
1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Data;
5 using System.Drawing;
6 using System.Linq;
7 using System.Text;
8 using System.Windows.Forms;
9 using System.Threading;
10
11 namespace InvokeTest
12 {
13 public partial class Form1 : Form
14 {
15 public Form1() {
16 InitializeComponent();
17 }
18
19 /**
20 * 对 委托 的 BeginInvoke,EndInvoke 及 Control 的 BeginInvoke,EndInvoke 的理解:
21 *
22 * 委托的 BeginInvoke,是使用 异步的方式. 它的参数1 是传入一个完成方法后调用的回调函数
23 * 参数2,是像 这个回调函数里传入的一个 Object 参数.
24 *
25 * EndInvoke ,是得到 委托方法的返回值. 如果委托方法没有返回值.那就只需要一个用来完成
26 * 后回调的方法即可. 如果有返回值的方法. 还是很有必要使用这个 EndInvoke 的.
27 *
28 * Control 上的 Invoke 及 BeginInvoke 都是运行在 UI 线程上的,所以都会造成 界面阻塞.
29 * 我们一般是使用委托的 BeginInvoke 去异步执行一些耗时方法.在 执行完后 的回调中使用
30 * Control.Invoke 方法去更新UI界面 如:
31 * this.Invoke(new Action(() => this.button1.Text = (string)ar.AsyncState));
32 */
33
34 // 如果调用 BeginInvoke 的方法没有返回值的话,只是在方法结束后调用一个 回调函数的话
35 // 则在 BeginInvoke 的时候就不必传入委托自身. 当然也不需要调用 EndInvoke 方法,得到
36 // 返回值了.
37 private void Form1_Load(object sender, EventArgs e) {
38 // 异步
39 (new Action(() => { Thread.Sleep(3000); })).BeginInvoke(new AsyncCallback((ar) => {
40 this.Invoke(new Action(() => this.button1.Text = (string)ar.AsyncState));
41 }), "KAOKAO");
42 }
43
44
45 // 如果你调用 BeginInvoke 的委托方法是有返回值的,那么你就需要在调用BeginInvoke的时候,把
46 // 委托的本身做为第二个参数传到 CallBack 函数中,在里面 通过 把 AsyncState 强转为我们的委托
47 // 类型, 然后就可以使用委托的 EndInvoke 方法,这个方法返回的就是 我们的委托函数所返回的值.
48 private void button1_Click(object sender, EventArgs e) {
49 // Func
50 Func<float> Func = new Func<float>(() => { Thread.Sleep(1000); return 123.456f; });
51
52 Func.BeginInvoke(new AsyncCallback((ar) => {
53 Func<float> tmp = (Func<float>)ar.AsyncState;
54 float tmpint = tmp.EndInvoke(ar);
55 this.Invoke(new Action(() => {
56 this.label1.Text = tmpint.ToString();
57 }));
58 }), Func);
59 }
60 }
61 }
