1. 异步编程

在.Net 4.5中,通过async和await两个关键字,引入了一种新的基于任务的异步编程模型(TAP)。在这种方式下,可以通过类似同步方式编写异步代码,极大简化了异步编程模型。如下式一个简单的实例:

static async void DownloadStringAsync2(Uri uri)
    {
        var webClient = new WebClient();
        var result = await webClient.DownloadStringTaskAsync(uri);
        Console.WriteLine(result);
    }

而之前的方式是这样的:

static void DownloadStringAsync(Uri uri)
    {
        var webClient = new WebClient();
        webClient.DownloadStringCompleted += (s, e) =>
            {
                Console.WriteLine(e.Result);
            };
        webClient.DownloadStringAsync(uri);
    }

也许前面这个例子不足以体现async和await带来的优越性,下面这个例子就明显多了:

public void CopyToAsyncTheHardWay(Stream source, Stream destination)
    {
        byte[] buffer = new byte[0x1000];
        Action<IAsyncResult> readWriteLoop = null;
        readWriteLoop = iar =>
        {
            for (bool isRead = (iar == null); ; isRead = !isRead)
            {
                switch (isRead)
                {
                    case true:
                        iar = source.BeginRead(buffer, 0, buffer.Length,
                            readResult =>
                            {
                                if (readResult.CompletedSynchronously) return;
                                readWriteLoop(readResult);
                            }, null);
                        if (!iar.CompletedSynchronously) return;
                        break;
                    case false:
                        int numRead = source.EndRead(iar);
                        if (numRead == 0)
                        {
                            return;
                        }
                        iar = destination.BeginWrite(buffer, 0, numRead,
                            writeResult =>
                            {
                                if (writeResult.CompletedSynchronously) return;
                                destination.EndWrite(writeResult);
                                readWriteLoop(null);
                            }, null);
                        if (!iar.CompletedSynchronously) return;
                        destination.EndWrite(iar);
                        break;
                }
            }
        };
        readWriteLoop(null);
    }

public async Task CopyToAsync(Stream source, Stream destination)
    {
        byte[] buffer = new byte[0x1000];
        int numRead;
        while ((numRead = await source.ReadAsync(buffer, 0, buffer.Length)) != 0)
        {
            await destination.WriteAsync(buffer, 0, numRead);
        }
    }

关于基于任务的异步编程模型需要介绍的地方还比较多,不是一两句能说完的,有空的话后面再专门写篇文章来详细介绍下。另外也可参看微软的官方网站:Visual Studio Asynchronous Programming,其官方文档Task-Based Asynchronous Pattern Overview介绍的非常详细, VisualStudio中自带的CSharp Language Specification中也有一些说明。

2. 调用方信息

很多时候,我们需要在运行过程中记录一些调测的日志信息,如下所示:

public void DoProcessing()
    {
        TraceMessage("Something happened.");
    }

为了调测方便,除了事件信息外,我们往往还需要知道发生该事件的代码位置以及调用栈信息。在C++中,我们可以通过定义一个宏,然后再宏中通过__FILE__和__LINE__来获取当前代码的位置,但C#并不支持宏,往往只能通过StackTrace来实现这一功能,但StackTrace却有不是很靠谱,常常获取不了我们所要的结果。

针对这个问题,在.Net 4.5中引入了三个Attribute:CallerMemberName、CallerFilePath和CallerLineNumber。在编译器的配合下,分别可以获取到调用函数(准确讲应该是成员)名称,调用文件及调用行号。上面的TraceMessage函数可以实现如下:

public void TraceMessage(string message,
            [CallerMemberName] string memberName = "",
            [CallerFilePath] string sourceFilePath = "",
            [CallerLineNumber] int sourceLineNumber = 0)
    {
        Trace.WriteLine("message: " + message);
        Trace.WriteLine("member name: " + memberName);
        Trace.WriteLine("source file path: " + sourceFilePath);
        Trace.WriteLine("source line number: " + sourceLineNumber);
    }

另外,在构造函数,析构函数、属性等特殊的地方调用CallerMemberName属性所标记的函数时,获取的值有所不同,其取值如下表所示:

调用的地方

CallerMemberName获取的结果

方法、属性或事件

方法,属性或事件的名称

构造函数

字符串 ".ctor"

静态构造函数

字符串 ".cctor"

析构函数

该字符串 "Finalize"

用户定义的运算符或转换

生成的名称成员,例如, "op_Addition"。

特性构造函数

特性所应用的成员的名称

例如,对于在属性中调用CallerMemberName所标记的函数即可获取属性名称,通过这种方式可以简化 INotifyPropertyChanged 接口的实现。

C# 5.0新加特性的更多相关文章

  1. C# 2.0新加特性

    泛型(Generics) 泛型是CLR 2.0中引入的最重要的新特性,使得可以在类.方法中对使用的类型进行参数化. 例如,这里定义了一个泛型类: class MyCollection<T> ...

  2. C# 7.0新加特性

    以下将是 C# 7.0 中所有计划的语言特性的描述.随着 Visual Studio “15” Preview 4 版本的发布,这些特性中的大部分将活跃起来.现在是时候来展示这些特性,你也告诉借此告诉 ...

  3. C# 6.0新加特性

    1.自动属性的增强 1.1.自动属性初始化 (Initializers for auto-properties) C#4.0下的果断实现不了的. C#6.0中自动属性的初始化方式 只要接触过C#的肯定 ...

  4. C# 4.0新加特性

    协变和逆变 这个在C#2.0中就已经支持委托的协变和逆变了,C#4.0开始支持针对泛型接口的协变和逆变: IList<string> strings = new List<strin ...

  5. C# 3.0新加特性

    类型推断 申明变量的时候,可以不用直指定类型: var i = 5; var s = "Hello"; //两种写法是一样的 int i = 5; string s = " ...

  6. LINQ体验(2)——C# 3.0新语言特性和改进(上篇)

    整体来说.Visual Studio 2008和.NET 3.5是建立在.NET2.0核心的基础之上,.NET2.0核心本身将不再变化(假设不了解.NET2.0的朋友,请參看MSDN或者一些经典的书籍 ...

  7. C# 3.0新语言特性和改进(一)

    引言 关于C#3.0的特性,园子里已经有了一大把,可能大家都很熟悉了,虽然本人开发中使用过,但自己还是需要记录一下,总结一下.同时也是后面写Linq知识的基础.希望有兴趣的朋友,可以看看. C# 3. ...

  8. Netty 4.0 新的特性及需要注意的地方

    Netty 4.0 新的特性及需要注意的地方 这篇文章和你一起过下Netty的主发行版本的一些显著的改变和新特性,让你在把你的应用程序转换到新版本的时候有个概念. 项目结构改变 Netty的包名从or ...

  9. dbt 0.13.0 新添加特性sources 试用

    dbt 0.13 添加了一个新的功能sources 我呢可以用来做以下事情 从基础模型的源表中进行数据选择 测试对于源数据的假设 计算源数据的freshness source 操作 定义source ...

随机推荐

  1. [转载]Linux内存高,触发oom-killer问题解决

    最近遇到两起Linux的内存问题,其一是触发了oom-killer导致系统挂 首先确认该系统的版本是32位 #uname -a Linux alarm 2.6.9-67.ELsmp #1 SMP We ...

  2. HDU 1241 Oil Deposits (DFS or BFS)

    链接 : Here! 思路 : 搜索判断连通块个数, 所以 $DFS$ 或则 $BFS$ 都行喽...., 首先记录一下整个地图中所有$Oil$的个数, 然后遍历整个地图, 从油田开始搜索它所能连通多 ...

  3. Modbus串行通信

    一.Modbus通信协议简介 1. Modbus协议 Modbus 是一个请求/应答协议,并且提供功能码规定的服务.Modbu协议是 OSI 模型第 7 层上的应用层报文传输协议. MODBUS协议支 ...

  4. PL\SQL(day05)

    PLSQL 1.常用的访问数据库的相关技术 1) plsql 过程化的sql 2) proc/c++ 在c/c++语言中访问oracle数据库的技术 3) ado/odbc vc中访问数据库的技术 4 ...

  5. 单例模式的理解【php】

    单例模式(Singleton Pattern):顾名思义,就是只有一个实例.作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例. 为什么要使用单例模式 1.P ...

  6. spi简介(自我理解)

    因为项目中用到spi总线,网上看了下资料,总感觉云山雾罩的,就向身边的同事问了下,他给我解释了下, 我现在把自己理解的写下来 spi一共四条线,一条选择线,一条数据线,2条数据线.spi是一对多设备, ...

  7. 手写一个简化版Tomcat

    一.Tomcat工作原理 我们启动Tomcat时双击的startup.bat文件的主要作用是找到catalina.bat,并且把参数传递给它,而catalina.bat中有这样一段话: Bootstr ...

  8. 1013MySQL监控利器-Innotop

    转自 http://www.cnblogs.com/ivictor/p/5101506.html 安装过程中 可以使用 YUM INSTALL INNOTOP进行直接安装 Innotop是一款十分强大 ...

  9. HDU 4521

    就是那个O(nlogn)的LIS算法. #include <iostream> #include <cstdio> using namespace std; int dt[10 ...

  10. Android之旅十六 android中各种资源的使用

    android中各种资源的使用: 在android开发中,各种资源的合理使用应该在各自的xml中进行定义,以便反复使用; 字符串资源:strings.xml,xml中引用:@string/XXX,ja ...