本文原文:Five Great .NET Framework 4.5 Features
译者:冰河魔法师

目录

介绍

微软的.Net 4.5框架已经发布了差不多一年了,和其他微软发布的产品有类似的缺乏沟通的问题,这个产品中只有一到两个特性是开发者们所知道的,剩下的那些直到最后都只能是在MSDN上面的一些简单文档而已。

比如说,当你问一个.Net程序员在.Net4.5中究竟有什么样的更新,他们多半会回答你说async和await(至少我周围的朋友是这样回答的)

当然,要想知道所有的特性点是非常困难的,毕竟有些特性在你的工作范围内一点都不涉及的情况下看起来好像也没什么用。

所以在这篇文章里,我选择了五个我最喜欢的特性来介绍。重申一下,我最喜欢的特性不一定是你最喜欢的,但是我在选择的时候已经尽量考虑选择大部分.Net程序员都会用到的,我希望我的文章能够达到这个期望。

注意:这篇文章讨论的新特性仅限于核心库(.Net 4.5 Core),不会涉及 ASP.NET, WCF, WPF, WWF等。

特性一:async和await

这个特性被大量的宣传过,而且几乎每个.Net讲师都会提及它,不过它依旧是我最爱的新特性,不用急,你马上就能知道为什么我这么喜爱它了。

asyncawait是一对标记符,可以用来标记当一个任务(线程)完成后将返回到哪里。

上面这句话有点拗口,所以我们还是一起来尝试用实际的代码来理解这句话。

首先我们来看看下面这段代码的执行步骤:

  1. main函数启动后,调用了Method()方法
  2. Method()方法里面用Task启动了一个LongTask函数(内容为等待10秒)
  3. 启动LongTask后会立即返回并执行Method()方法中的剩余代码。换句话说,启动多线程(Task.Run)后,LongTask在运行,而Method()方法中剩余的代码也能被执行

接下来我们希望第三步执行的行为变化一下,我们希望在执行完LongTask()后才回到Method()方法继续执行剩余的代码。这里我们使用asyncawait关键字来实现上述行为。

这里有三点需要注意的地方:

  1. asyncawait是成对出现的,独立是无法使用的
  2. async是标记方法的,这个标记只是指示出该方法中将包含await关键字
  3. await关键字标记了任务执行结束后需要返回到的位置,所以你常常会将该关键字与Task类联用。

下面这幅图是将我们之前讨论过的代码使用asyncawait改造过后的版本,除了第三步是在第二步执行完成后执行的外,其他部分都是和以前一样的。简单来说就是只会在任务LongTask执行完成后才会回到Method()中继续执行。

现在你已经了解了asyncawait,我来问一个问题权当家庭作业吧:使用Task.WaitTask.ContineWith方法也可以达到同样的效果,不过他们有什么差别呢?

特性二:Zip压缩

Zip格式是现在接受程度最高之一的压缩档案格式。几乎所有操作系统都支持操作该格式。

在以前的.Net版本中都没有内建对Zip压缩功能的支持,所以通常情况开发人员都会使用第三方的类似于DotnetZip之类的组件来达到该效果。不过在.Net4.5中,Zip压缩格式已经被内置到框架中去了,在System.IO.Compression命名空间中。

要使用它,我们就先引用一下两个命名空间:

  • System.IO.Compression.FileSystem
  • System.IO.Comptession

接下来将其引入代码:

using System.IO.Compression;

如果你想将一个文件夹中的所有文件都打包进来,就使用CreateFromDirectory方法:

ZipFile.CreateFromDirectory(@"D:\data",@"D:\data.zip");

如果你想解压,可以使用ExtractToDirectory方法:

ZipFile.ExtractToDirectory(@"D:\data.zip", @"D:\data\unzip");

特性三:正则表达式执行超时

正则表达式是做字符串类验证的最好方式,如果你是第一次接触正则表达式,推荐你看一段视频,但是标准的正则表达式逻辑却会给黑客们留下DoS(拒绝服务)攻击的可能性,我接下来详细的说明会让你明白这是为什么。

假如我们有个正则表达式^(\d+)$,这个正则表达式希望这个字符串里只包含数字。你可以观察正则表达式符号图(Regex Symbolic Diagram)来了解正则表达式是如何被计算的。如果我们要验证字符串123456X,将会有6条路径来验证,如下图:

但是如果我们多加一个数字进去,将会变成7条路径。换句话说,随着字符串长度的增长,正则表达式将会花掉更多的时间来计算,再换句话说,计算时间和字符串长度是成线型比例的。

我们将之前定义的正则表达式变成更复杂的^(\d+)+$,你将看到正则表达式的计算过程变得更加复杂,如果我们试图验证字符串123456X,将会计算32条路径,只要你将字符串加长一个字符,将会计算64条路径

换句话说,计算时间将会随着字符串的增加而成倍增加。

现在你有可能会问,这个有什么关系呢?这种超长的计算时间很有可能会被黑客发现来做DoS攻击,他们只需要向你的服务器请求一个超长的字符串要验证,你的服务器将会一直等在那里。

当然,解决这个问题的最佳方案就是在用正则表达式做验证的时候设置一个超时时间。在.Net4.5中就有这个功能,像如下代码中那样就可以。从此之后,哪怕用户发来了恶意字符串,我们的程序也不会卡死在那里。

try
{
var regEx = new Regex(@"^(\d+)+$", RegexOptions.Singleline, TimeSpan.FromSeconds(2));
var match = regEx.Match("123453109839109283090492309480329489812093809x");
}
catch (RegexMatchTimeoutException ex)
{
Console.WriteLine("Regex Timeout");
}

特性四:配置(Profile)优化(提高启动性能)

我们都知道.Net的程序二进制文件是IL格式的,在运行时,由JIT(Just-in-Time)编译器即时的将IL代码转译成机器代码。因此我们常常都会抱怨.Net程序的启动速度缓慢,我们总是需要等待JIT将IL代码转换成机器代码。

为了提高启动效率,在.Net4.5中,我们有一个称之为配置优化(Profile Optimization)的机制。配置其实仅仅是一个含有程序启动时所需方法列表的简单文件,所以当程序启动的时候,后台JIT(Backgroud JIT)运行并转译这些方法至机器代码。

后台JIT编译启动方法的过程会使用多核进行,以得到更高的启动效率。必须注意的是 你必须使用多核CPU来实现配置优化 。如果你没有多核CPU,那么这些设置将会被忽略。

为了创建一个配置文件,你首先需要引入System.Runtime命名空间,然后你就可以调用在类ProfileOptimization中的SetProfileRootStartProfile方法。于是,当程序启动,后台JIT便会读取配置文件并且在后台编译你的启动方法,以此来减少启动时间。

using System.Runtime;

// Call the Setprofilerroot and Startprofile method
ProfileOptimization.SetProfileRoot(@"D:\ProfileFile"); ProfileOptimization.StartProfile("ProfileFile");

有一点需要注意:ProfileOptimization默认对于ASP.NET 4.5和Silverlight 5是开启的,所以对于它们来说不用手动写这些代码来开启。

特性五:垃圾回收(GC)(后台GC垃圾清理)

对于.Net程序来说,垃圾回收(GC)的确是一件非常繁重和频繁(heavy)的任务。尤其是在ASP.NET程序中,大量的请求使得服务器建立了大量的对象,使得GC必须努力的工作以便把这些不需要的对象清理掉。

在.Net4.0中,当GC执行清理的时候,所有的程序线程均被暂停了。在上图中,我们有三个线程运行以及两个GC运行在不同的线程(并在独立的逻辑处理器上运行)中,现在程序线程运行并执行它们自己的任务(这些任务均会创建一些对象)。

在某个时间点后台GC执行清理,当它们执行清理的时候,所有其他程序线程均会被暂停。这样就使得程序在那个时候会短暂的失去响应。

为了克服以上这个问题,服务器GC(Server GC)因此而生,在服务器GC中,将会多一个线程运行在后台,用来在后台清理Gen 2(观看这段视频来了解GC Gen 0,1,2)的对象使得主GC线程的负载减小,由于两个GC线程在运行,这样使得主应用线程变得更短的暂停,因此而提高了应用程序的吞吐率(throughput)。要启用服务器GC,只需要添加gcServerXML标签并将其设为true即可:

<configuration>
<runtime>
<gcServer enabled="true"/>
</runtime>
</configuration>

另外三个值得探索的新特性

设置应用域级别缺省Culture

在之前的.Net版本中如果我们需要设置Culture,需要在每一个线程中设置Culture。下面这段代码就演示我们在线程级别设置Culture的痛苦之处。而且如果我们的程序是重多线程程序,那会是更加的痛苦。

CultureInfo cul = new CultureInfo(strCulture);
Thread.CurrentThread.CurrentCulture = cul;
Thread.CurrentThread.CurrentUICulture = cul;

在4.5中,我们可以在应用域(App Domain)级别设置Culture,然后所有该应用域的线程均会继承该Culture,下面就演示了如何使用DefaultThreadCurrentCulture

CultureInfo culture = CultureInfo.CreateSpecificCulture("fr-FR");
CultureInfo.DefaultThreadCurrentCulture = culture;

数组支持超过2G大小

其实我也不确定什么样的场景需要2G大小的集合。所以我个人来看,我并不知道什么时候这个特性会被用到,通常情况如果我们需要大集合的时候都会把它分散为小部分。不过我相信一定有足够重要的理由让.Net4.5支持这个特性。

控制台支持Unicode

我想应该很少人会用控制台把,不过我看见过一些人使用控制台来做学术研究目的。不管怎么样,我们现在可以有支持Unicode的控制台了。

参考文献

译者注

本文作者推荐了两个视频来服务初学者,使其了解一些基本概念,不过若需观看请自行翻墙。

[译].Net 4.5 的五项强大新特性的更多相关文章

  1. Java9都快发布了,Java8的十大新特性你了解多少呢?

    Java 9预计将于今年9月份发布,这是否会是一次里程碑式的版本,我们拭目以待.今天,我们先来复习一下2014年发布的Java 8的十大新特性. Java 8可谓是自Java 5以来最具革命性的版本了 ...

  2. ES6的十大新特性(转)

    add by zhj: 该文章是由国外一哥们写的,由腾讯前端团队翻译,图片中的妹子长得挺好看的,很养眼,嘿嘿.我目前在学习ES6,这篇文章把ES6的 几个主要新特性进行了归纳总结,犹如脑图一般,让人看 ...

  3. java8的十大新特性

    推荐学习的博客: http://blog.csdn.net/renfufei/article/details/24600507/-------讲解的非常通俗易懂 http://blog.csdn.ne ...

  4. Java基础学习总结(33)——Java8 十大新特性详解

    Java8 十大新特性详解 本教程将Java8的新特新逐一列出,并将使用简单的代码示例来指导你如何使用默认接口方法,lambda表达式,方法引用以及多重Annotation,之后你将会学到最新的API ...

  5. 有史来最大改变 Android 5.0十大新特性

    有史来最大改变 Android 5.0十大新特性 2014.10.16 14:51:31 来源:腾讯数码作者:腾讯数码 ( 0 条评论 )   距离Android系统上一次重大更新不到一年的时间,谷歌 ...

  6. Android 5.0(棒棒糖))十大新特性

    Android 5.0(棒棒糖))十大新特性 1. 全新Material Design设计风格 Android Lollipop全新的设计语言是受到了多种因素影响,是一种大胆的平面化创新.换句话说,谷 ...

  7. Java9发布回顾Java 8的十大新特性

    java9已经在北京时间9月22日正式发布,开发者可以在oracle jdk官网上下载到最新的jdk9. 今天,我们先来一起复习一下2014年发布的Java 8的十大新特性.先来喝杯java~~~ 按 ...

  8. C# 9.0 终于来了, Top-level programs 和 Partial Methods 两大新特性探究

    一:背景 1. 讲故事 .NET 5 终于在 6月25日 发布了第六个预览版,随之而来的是更多的新特性加入到了 C# 9 Preview 中,这个系列也可以继续往下写了,废话不多说,今天来看一下 To ...

  9. Java8 十大新特性详解(转)

    本教程将Java8的新特新逐一列出,并将使用简单的代码示例来指导你如何使用默认接口方法,lambda表达式,方法引用以及多重Annotation,之后你将会学到最新的API上的改进,比如流,函数式接口 ...

随机推荐

  1. Java求两个数平均值

    如何正确的求2个数的平均值.在练习算法二分查找的时候发现的,以前没有注意到的bug 备注:数据以int类型为例 一.以前的通用写法 /** * 求a+b平均值 * @param a * @param ...

  2. hdu 3874(树状数组)题解

    Problem Description Mery has a beautiful necklace. The necklace is made up of N magic balls. Each ba ...

  3. hdu 6180 Schedule

    Schedule Problem Description There are N schedules, the i-th schedule has start time si and end time ...

  4. 基于nodejs环境,用npm简单搭建一个本地服务器Live-server的使用

    用npm 或者cnpm进行全局安装 cnpm install -g live-server 运行后就可以直接给你虚拟一个本地服务器,而且还可以热同步 运行 live-server

  5. label表单的关联性

    <input type="checkbox" id="cr" /> <label for="cr">点击关联复选框& ...

  6. attr返回被选元素的属性值

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. 使用Docfx生成项目文档

    使用docfx.console生成本项目的文档 使用docfx.console生成其他项目的文档 直接使用docfx.exe生成项目文档 指定配置文档模板   文档地址:http://gitlab.l ...

  8. 《算法竞赛入门经典》习题及反思 -<2>

    数组 Master-Mind Hints,Uva 340 题目:给定答案序列和用户猜的序列,统计有多少数字对应正确(A),有多少数字在两个序列都出现过但位置不对. 输入包括多组数据.每组输入第一行为序 ...

  9. windows与kali双系统安装基本教程

    以前写过一篇在虚拟机中安装kali的基本教程的文章,那时候的kali还是1.0时代,现如今已经kali2.0了,在虚拟机中运行kali还是会受到性能的影响,所以还是装到自己电脑上跑起来最爽.当然如果你 ...

  10. VC6_导入lib库

    http://www.cnblogs.com/webcyz/p/3525166.html 2. 导入lib库.导入的方法很多方法1) 直接用project>add to project>f ...