使用匿名委托,Lambda简化多线程代码
使用匿名委托,Lambda简化多线程代码
.net中的线程也接触不少了。在多线程中最常见的应用莫过于有一个耗时的操作需要放到线程中去操作,而在这个线程中我们需要更新UI,这个时候就要创建一个委托了来更新UI了,不然会报错的。下面我们就来设计一个简单的场景:窗体上有一个按钮和进度条,按钮按下后启动一个线程让进度条滚动。需要说明一下的是,我们这里不讨论使用匿名委托,lambda的好坏,我们只有一个目标就是使得我们的程序:短点,短点,再短点。
我刚开始没有掌握匿名方法这些就是按照下面这些写的,说实话很痛苦。后来接触了匿名表达式,lambda后几乎都不想再想写这样的东西了,除非特殊的一些情况,比如需要自己定义委托。如果您现在还在按照下面这样写,那么这篇文章对你或许有些帮助!
//声明一个委托
delegate void UpdateProgressDelegate();
//声明一个UpdateProgressDelegate的委托实例
private UpdateProgressDelegate UpdateProgressHandle; public Form1()
{
InitializeComponent();
progressBar1.Maximum = 100;
progressBar1.Minimum = 0;
progressBar1.Value = 0;
//将该委托实例和UpdateProgressValue方法绑定起来
UpdateProgressHandle = new UpdateProgressDelegate(UpdateProgressValue);
} private void button1_Click(object sender, EventArgs e)
{
Thread t = new Thread(new ThreadStart(D));
t.Start();
} private void D()
{
//其他事情
//..........
progressBar1.Invoke(UpdateProgressHandle); //调用Invoke更新进度条,参数是我们新建的委托
} //更新进度条的方法
private void UpdateProgressValue()
{
for (int i = 0; i < 50; i++)
{
progressBar1.Value = i;
}
}
这个写法基本就是.net 1.x里面的委托写法了。您也看出来,很繁琐。像一个多线程的界面中,要和多线程打交道的控件何止一个两个。几个一来就会感觉很烦了。维护起来也不方便。下面我们使用.net 2.0中的一个新特性:支持省略委托的创建,直接将方法名字赋给需要的参数。即我们可以将
Thread t = new Thread(new ThreadStart(D));
改为:
Thread t = new Thread(D);
虽然只是少了一点,不过好歹也是个进步对吧。
现在我们引入.net 2.0中的匿名委托来改善下上面这个程序,使其看起来更加简洁点。怎样使用匿名委托?教你个简单的方法,程序中参数是方法名字的地方您都可以通过delegate(){//操作}的形式来代换。比如下面我们就像D方法名那里给替换掉。
//声明一个委托
delegate void UpdateProgressDelegate();
//声明一个UpdateProgressDelegate的委托实例
private UpdateProgressDelegate UpdateProgressHandle; public Form1()
{
InitializeComponent();
progressBar1.Maximum = 100;
progressBar1.Minimum = 0;
progressBar1.Value = 0;
//将该委托实例和UpdateProgressValue方法绑定起来
UpdateProgressHandle = new UpdateProgressDelegate(UpdateProgressValue);
} private void button1_Click(object sender, EventArgs e)
{
Thread t = new Thread(delegate() { progressBar1.Invoke(UpdateProgressHandle); });
t.Start();
} //更新进度条的方法
private void UpdateProgressValue()
{
for (int i = 0; i < 50; i++)
{
progressBar1.Value = i;
}
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
progressBar1.Maximum = 100;
progressBar1.Minimum = 0;
progressBar1.Value = 0;
} private void button1_Click(object sender, EventArgs e)
{
Thread t = new Thread(delegate() { progressBar1.Invoke(new Action(UpdateProgressValue)); });
t.Start();
} //更新进度条的方法
private void UpdateProgressValue()
{
for (int i = 0; i < 50; i++)
{
progressBar1.Value = i;
}
}
}
可以看到我们之前声明的那一长段的委托都去掉了,清爽了不少。那么在.net 2中该如何使用呢?两个办法:
1.强制在UpdateProgressValue中加个参数,但我们不使用。代码如下:

代码
2.不使用Action委托,还记得我们最朴素写法中的ThreadStart这个委托吗?这个就是一个现成的无参数委托,不用白不用!代码如下:

代码
上面我们已经说过了,有方法名为参数的地方可以使用匿名方法替代,那么上面的那个new Action(UpdateProgressValue)中的UpdateProgressValue我们同样可以再给替换掉了。代码如下:

代码
我们最后引入lambda来简化我们的代码。Lambda表达式在C#中的写法是“arg-list => expr-body”,“=>”符号左边为表达式的参数列表,右边则是表达式体(body)。参数列表可以包含0到多个参数,参数之间使用逗号分割。当然因为我们这里没有参数所有可以直接写成()=>{}的形式了啦。lambda用在哪里呢?它可以替换匿名表达式使其更加简单,在LINQ等等查询语句中也有使用,不过不是我们今天讨论的范围。如何替换匿名表达式呢?代码如下:

private void button1_Click(object sender, EventArgs e)
{
Thread t = new Thread(() => progressBar1.Invoke(new Action(()=>
{
for (int i = 0; i < 50; i++)
{
progressBar1.Value = i;
}
})));
t.Start();
}

可以看到使用了lambda后匿名方法中的一些不需要的{}被省略了,自然看起来也就爽多啦。如果非要总结一个怎么替换的过程的话那就简单的认为将delegate(){}替换为了()=>{},如果有参数类似。
最后需要说的是别看我们上面的代码样子好像变化了不少,其实在编译后编译器会为我们上面省略的一系列代码再加上去的。有兴趣的可以看看简化后的IL和没有简化的IL,其实都是差不多的。好了,这就是我目前能达到的最短代码了。如果您还能再短些欢迎提出!
使用匿名委托,Lambda简化多线程代码的更多相关文章
- Unity C# 多态 委托 事件 匿名委托 Lambda表达式 观察者模式 .NET 框架中的委托和事件
一.多态 里氏替换原则: 任何能用基类的地方,可以用子类代替,反过来不行.子类能够在基类的基础上增加新的行为.面向对象设计的基本原则之一. 开放封闭原则: 对扩展开放,意味着有新的需求或变化时,可以对 ...
- C#学习笔记(28)——匿名委托和Lambda表达式
说明(2017-11-21 18:51:32): 1. 例子为求1~100的和,答案应该是5050(小学学算盘的时候,我爹就让我算,从1拨到100是多少呀?当时的我年幼无知,还不知道高斯小时候的故事, ...
- C#委托,匿名方法,Lambda,泛型委托,表达式树代码示例
第一分钟:委托 有些教材,博客说到委托都会提到事件,虽然事件是委托的一个实例,但是为了理解起来更简单,今天只谈委托不谈事件.先上一段代码: 下边的代码,完成了一个委托应用的演示.一个委托分三个步骤: ...
- 委托、匿名委托、Lambda 表达式、Expression表达式树之刨根问底
本篇不是对标题所述之概念的入门文章,重点在阐述它们的异同点和应用场景.各位看官,这里就不啰嗦了,直接上代码. 首先定义一个泛型委托类型,如下: public delegate T Function&l ...
- 匿名委托与Lambda表达式
通过使用匿名委托(匿名方法),使编程变得更加灵活,有关委托与匿名委托请参考我的前一篇Blog<委托与匿名委托>. 继续之前示例,代码如下: static void Main(string[ ...
- .net 系列:Expression表达式树、lambda、匿名委托 的使用
首先定义一个泛型委托类型,如下: public delegate T Function<T>(T a, T b); 实现泛型委托的主体代码,并调用: public static strin ...
- .net 系列:Expression表达式树、lambda、匿名委托 的使用【转】
https://www.cnblogs.com/nicholashjh/p/7928205.html 首先定义一个泛型委托类型,如下: public delegate T Function<T& ...
- C#委托总结-匿名方法&Lambda表达式
1,匿名方法 匿名方法可以在声明委托变量时初始化表达式,语法如下 之前写过这么一段代码: delegate void MyDel(string value); class Program { void ...
- 匹夫细说C#:委托的简化语法,聊聊匿名方法和闭包
0x00 前言 通过上一篇博客<匹夫细说C#:庖丁解牛聊委托,那些编译器藏的和U3D给的>的内容,我们实现了使用委托来构建我们自己的消息系统的过程.但是在日常的开发中,仍然有很多开发者因为 ...
随机推荐
- Magento控制器
提到模型-视图-控制器这种MVC架构,要追溯到Smalltalk编程语言和Xerox Parc.从那个时候开始,就有许多系统将自己描述为MVC架构.这些系统虽然在某些地方有细微差别,但都实现了数据层, ...
- Magento中调用JS文件的几种方法
一.全局调用方法: 通过该方法每个页面都会引用这个JS文件,除非是类似jQuery这样的系统文件,不然不推荐这种方法. 文件路径:/app/design/frontend/default/Your_T ...
- shell脚本 gawk语言 综采话单 对账 字段核对
今天被分配到对账组下的字段程序的了解和修改,在 SecureCRT 下的 run.sh 是字段对账的主程序,其中run.sh文件中含有gawk的代码. 程序的主要功能为 有两个文件夹 source存的 ...
- Python 如何跳出多重循环
Python 如何跳出多重循环 抛异常 return
- Dubbo_Admin安装
1.下载dubbo 我上传地址:http://download.csdn.net/detail/liweifengwf/7784901 官方地址:http://code.alibabatech.com ...
- PHP 中安装memcache扩展文件下载对应地址。
PHP 5.5.1版本下载了很多,安装都不成功.终于找到一个适合版本. http://windows.php.net/downloads/pecl/releases/memcache/3.0.8/ ...
- php中能够获取到某一网站内容的方法
方法一:file_get_contents 函数 example: <?php $url = "http://www.cnblogs.com"; $contents = fi ...
- jsb里出现的 Invalid Native Object的一次bug修复的思考
Cocos2d: jsb: ERROR: File /Users/dcx_JD/Documents/cocos2d-x-2.2.2/scripting/javascript/bindings/gene ...
- ABySS 拼接工具
ABySS, that stands for Assembly By Short Sequences, is a de novo, parallel, paired-end sequence asse ...
- 这是高手最常用的第一快捷组合键 - imsoft.cnblogs
1.锁定电脑 2.要找电脑上的文件时,一般人会先找到“我的电脑”,然后点击打开,而高手总是很酷的,轻轻按下键盘上的Windows键不放然后再按E键,直接打开电脑的资源管理器,而一般人还在慢慢寻找“我的 ...