其实我们应该一直很熟悉委托、匿名方法、Lambda表达式的关系的,作用差不多,写法却越来越简单,当然相互之间却不能完全代替的。今天研究了一下Lambda表达式的替换。
要求建立一个winform窗体,拖一Button控件,点击Button,执行一个耗时操作(用多线程),耗时操作结束后,在窗体上显示结束信息。
要求很简洁,解法也很简单。
一般解法
1
//
………………
2 using System.Threading;
3 namespace WindowsFormsApplication1
4 {
5 public partial class Form1 : Form
6 {
7 public Form1()
8 {
9 InitializeComponent();
10 }
11
12 /// 耗时操作
13 private string Work()
14 {
15 /// 1
16 Thread.Sleep( 20 * 1000 );
17 return " 耗时操作结束! " ; // 耗时操作结束,返回结束信息
18 }
19
20 /// 封装耗时操作的委托
21 delegate string WorkDelegate();
22
23 /// 委托变量
24 WorkDelegate myDelegate;
25
26 /// 点击button事件
27 private void Button1_Click( object sender,EventArgs e)
28 {
29 /// 2
30 myDelegate = new WorkDelegate(Work);
31 myDelegate.BeginInvoke( new AsyncCallBack(EndWork), null ); // 异步开始调用委托
32 }
33
34 /// 回调
35 private void EndWork(IAsyncResult ar)
36 {
37 /// 3
38 string result = myDelegate.EndInvoke(ar); // 结束异步委托调用
39 this .Invoke( new Action < string > (Single),result); // 这里注意,Button控件不在该线程,需要用Control.Invoke方法
40 }
41
42 /// 耗时操作结束后,显示信息
43 private void Single( string msg)
44 {
45 this .Button1.Text = msg; // 将信息显示在Button1上
46 }
47
48
49 /// 1和3属于同一线程,2属于主线程,Button1属于主线程,所以在3处更改控件属性需要用Invoke
50 }
51 }
2 using System.Threading;
3 namespace WindowsFormsApplication1
4 {
5 public partial class Form1 : Form
6 {
7 public Form1()
8 {
9 InitializeComponent();
10 }
11
12 /// 耗时操作
13 private string Work()
14 {
15 /// 1
16 Thread.Sleep( 20 * 1000 );
17 return " 耗时操作结束! " ; // 耗时操作结束,返回结束信息
18 }
19
20 /// 封装耗时操作的委托
21 delegate string WorkDelegate();
22
23 /// 委托变量
24 WorkDelegate myDelegate;
25
26 /// 点击button事件
27 private void Button1_Click( object sender,EventArgs e)
28 {
29 /// 2
30 myDelegate = new WorkDelegate(Work);
31 myDelegate.BeginInvoke( new AsyncCallBack(EndWork), null ); // 异步开始调用委托
32 }
33
34 /// 回调
35 private void EndWork(IAsyncResult ar)
36 {
37 /// 3
38 string result = myDelegate.EndInvoke(ar); // 结束异步委托调用
39 this .Invoke( new Action < string > (Single),result); // 这里注意,Button控件不在该线程,需要用Control.Invoke方法
40 }
41
42 /// 耗时操作结束后,显示信息
43 private void Single( string msg)
44 {
45 this .Button1.Text = msg; // 将信息显示在Button1上
46 }
47
48
49 /// 1和3属于同一线程,2属于主线程,Button1属于主线程,所以在3处更改控件属性需要用Invoke
50 }
51 }
现在看一下用Lamnda表达式的解法
简化后的解法
1
//
……
2 using System.Threading;
3 namespace WindowsFormsApplication1
4 {
5 public partial class Form1 : Form
6 {
7 public Form1()
8 {
9 InitializeComponent();
10 Debug.Listeners.Add( new ConsoleTraceListener());
11 }
12
13 /// 点击Button1
14 private void Button1_Click( object sender,EventArgs e)
15 {
16 Func < string > myDelegate = () => {Thread.Sleep( 20 * 1000 ); return " 耗时操作结束! " ;}; // 直接用Lambda表达式代替New委托
17 myDelegate.BeginInvoke((IAsyncResult ar) => { string re = myDelegate.EndInvoke(ar); this .Invoke( new Action < string > (Single),re );}); // Lambda表达式代替委托
18 }
19
20
21 private void Single( string msg)
22 {
23 this .Button1.Text = msg;
24 }
25 }
26 }
2 using System.Threading;
3 namespace WindowsFormsApplication1
4 {
5 public partial class Form1 : Form
6 {
7 public Form1()
8 {
9 InitializeComponent();
10 Debug.Listeners.Add( new ConsoleTraceListener());
11 }
12
13 /// 点击Button1
14 private void Button1_Click( object sender,EventArgs e)
15 {
16 Func < string > myDelegate = () => {Thread.Sleep( 20 * 1000 ); return " 耗时操作结束! " ;}; // 直接用Lambda表达式代替New委托
17 myDelegate.BeginInvoke((IAsyncResult ar) => { string re = myDelegate.EndInvoke(ar); this .Invoke( new Action < string > (Single),re );}); // Lambda表达式代替委托
18 }
19
20
21 private void Single( string msg)
22 {
23 this .Button1.Text = msg;
24 }
25 }
26 }
是不是比第一个简单多了呢?呵呵