在说Asnc和Await之前,先说明一下Func和Action委托, Task任务的基础的用法

1. Func

Func是一种委托,这是在3.5里面新增的,2.0里面我们使用委托是用Delegate,Func位于System.Core命名空间下,使用委托可以提升效率,例如在反射中使用就可以弥补反射所损失的性能。

Action<T>和Func<T,TResult>的功能是一样的,只是Action<T>没有返类型,

Func<T,T,Result>:有参数,有返回类型
Action,则既没有返回也没有参数,

Func<T,TResult>
的表现形式分为以下几种:

1。Func<T,TResult>
2。Func<T,T1,TResult>
3。Func<T,T1,T2,TResult>
4。Func<T,T1,T2,T3,TResult>
5。Func<T,T1,T2,T3,T4,TResult>

分别说一下各个参数的意义,TResult表示
委托所返回值 所代表的类型, T,T1,T2,T3,T4表示委托所调用的方法的参数类型,

以下是使用示例:

 1 Func<int, bool> myFunc = null;//全部变量
2
3 myFunc = x => CheckIsInt32(x);
4 //给委托封装方法的地方 使用了Lambda表达式
5
6 private bool CheckIsInt32(int pars)//被封装的方法
7 {
8   return pars == 5;
9 }
10
11 bool ok = myFunc(5);//调用委托

MSDN:http://msdn.microsoft.com/zh-cn/library/bb534303(VS.95).aspx

2. Action

但是如果我们需要所封装的方法不返回值,增么办呢?就使用Action!

可以使用
Action<T1, T2, T3, T4>委托以参数形式传递方法,而不用显式声明自定义的委托。封装的方法必须与此委托定义的方法签名相对应。也就是说,封装的方法必须具有四个均通过值传递给它的参数,并且不能返回值。(在 C# 中,该方法必须返回 void。在 Visual Basic 中,必须通过 Sub…End Sub 结构来定义它。)通常,这种方法用于执行某个操作。

使用方法和Func类似!

Action:既没有返回,也没有参数,使用方式如下:

1 Action action = null;//定义action
2
3 action = CheckIsVoid;//封装方法,只需要方法的名字
4
5 action();//调用

MSDN:http://msdn.microsoft.com/zh-cn/library/bb548654(VS.95).aspx

总结:

使用Func<T,TResult>和Action<T>,Action而不使用Delegate其实都是为了简化代码,使用更少的代码达到相同的效果,不需要我们显示的声明一个委托。

Func<T,TResult>的最后一个参数始终是返回类型,而Action<T>是没有返回类型的,而Action是没有返回类型和参数输入的.

3. Task

使用 Async 和 Await 的异步编程(msdn的好文章) :  https://msdn.microsoft.com/zh-cn/library/hh191443(v=vs.120)

Task基本使用: C# 线程知识--使用Task执行异步操作

Task和await结合返回值见: .NET(C#):await返回Task的async方法

Task深入了解见: C# Task的使用

总结: Task提供一种新的类似多线程的多任务的用法, 达到使用线程的效果,但具体怎么分配线程由.net底层控制,这样性能好,效率也高,我们只需要专注业务逻辑, 同时具备以前线程不具备的返回值的功能(可以通过回调事件来处理),而在Task中只是简单的使用await来使用, await的task相当于同步的调用task, 同时会有返回值,只是在书写方面需要注意async, task,func, action等等关键字的使用,新手可能很困惑, 下面的例子就是一个简单的task使用例子,新手注意注释!!!

 1 static void Main(string[] args)
2 {
3 //异步方法, 当中使用await可以执行task异步任务,否则当作同步执行
4 test();
5 //其次输出,因为异步进入task任务了,就同步执行当前线程下面的代码
6 log("Main:调用test后");
7 Thread.Sleep(Timeout.Infinite);
8 }
9
10 //Main方法不允许加async,所以我们用这个方法使用await
11 static async void test()
12 {
13 //最先输出,还没有进入task
14 log("test: await之前");
15 // await后的内容会被加在目标doo的Task的后面,然后test马上返回,而doo则是进入了另一个任务执行了
16 log("doo的Task的结果: " + await doo());
17 // 会等到上面await执行的任务完成后才会执行当前代码
18 log("test: await之后");
19 }
20 //返回Task的async方法, 一个标准的带返回值的异步task任务方法
21 static async Task<int> doo()
22 {
23 // 简单的说, async中使用await就是异步中以同步方式执行Task任务的方法,task任务一个接一个执行.
24 var res1 = await Task.Run(() => { Thread.Sleep(1000); log("Awaited Task1 执行"); return 1; });
25 var res2 = await Task.Run(() => { Thread.Sleep(1000); log("Awaited Task2 执行"); return 2; });
26 var res3 = await Task.Run(() => { Thread.Sleep(1000); log("Awaited Task3 执行"); return 3; });
27
28 //不使用await:线程池多线程, 当前task不会等这个执行完,因为不是await,只是又开启了一个线程
29 ThreadPool.QueueUserWorkItem(_ =>
30 {
31 Thread.Sleep(1000);
32 log("ThreadPool.QueueUserWorkItem: 线程池多线程执行");
33 });
34
35 //不使用await:Task多线程, 当前task不会等这个执行完,因为不是await,只是又开启了一个任务
36 Task.Run(() =>
37 {
38 Thread.Sleep(1000);
39 log("Task.Run: Task多线程执行");
40
41 });
42    
43 return res1 + res2 + res3;
44 }
45 //输出方法:显示当前线程号和输出信息
46 static void log(string msg)
47 {
48 Console.WriteLine("线程{0}: {1}", Thread.CurrentThread.ManagedThreadId, msg);
49 }

执行结果如下:

4. Async、Await

这个是.NET 4.5的特性,所以要求最低.NET版本为4.5。

看很多朋友还是使用的Thread来使用异步多线程操作,基本上看不见有使用Async、Await进行异步编程的。各有所爱吧,其实都可以。只要正确使用就行,不过还是写了这篇文章推荐大家使用Async、Await。 原因就是:可以跟写同步方法一样去异步编程。代码则就非常的清晰,就跟写普通的代码一样,不用关系如何去异步编程,也让很多初级程序员也能够异步编程了。下面是一个使用Thread 多线程实现的异步例子,以及一个使用Async与Await的异步例子,接下来我们再简单理解下Async与Await的相关技术说明。

Thread多线程异步编程例子

class Program
{
static void Main(string[] args)
{
Console.WriteLine("主线程测试开始..");
Thread th = new Thread(ThMethod);
th.Start();
Thread.Sleep(1000);
Console.WriteLine("主线程测试结束..");
Console.ReadLine();
} static void ThMethod()
{
Console.WriteLine("异步执行开始");
for (int i = 0; i < 5; i++)
{
Console.WriteLine("异步执行" + i.ToString() + "..");
Thread.Sleep(1000);
}
Console.WriteLine("异步执行完成");
}
}

  

以上代码运行效果如下图

使用Async与Await进行异步编程

 1 static void Main(string[] args)
2 {
3 Console.WriteLine("主线程测试开始..");
4 AsyncMethod();
5 Thread.Sleep(1000);
6 Console.WriteLine("主线程测试结束..");
7 Console.ReadLine();
8 }
9
10 static async void AsyncMethod()
11 {
12 Console.WriteLine("开始异步代码");
13 var result = await MyMethod();
14 Console.WriteLine("异步代码执行完毕" + result.ToString());
15 }
16
17 static async Task<int> MyMethod()
18 {
19 for (int i = 0; i < 5; i++)
20 {
21 Console.WriteLine("异步执行" + i.ToString() + "..");
22 await Task.Delay(1000); //模拟耗时操作
23 }
24 return 100;
25 }

运行效果:

显而易见我们就跟写同步方法一样,完成了异步方法的编写,代码更清晰了。

只有拥有async才能在其内部使用await关键字。异步方法可以具有Task、Task<>或void的返回类型;

await关键字则是用于返回值是“可等待”类型(awaitable)的方法

C# Task中的Func, Action, Async与Await的使用的更多相关文章

  1. 那些年我们一起追逐的多线程(Thread、ThreadPool、委托异步调用、Task/TaskFactory、Parallerl、async和await)

    一. 背景 在刚接触开发的头几年里,说实话,根本不考虑多线程的这个问题,貌似那时候脑子里也有没有多线程的这个概念,所有的业务都是一个线程来处理,不考虑性能问题,当然也没有考虑多线程操作一条记录存在的并 ...

  2. C#中的异步编程Async 和 Await

    谈到C#中的异步编程,离不开Async和Await关键字 谈到异步编程,首先我们就要明白到底什么是异步编程. 平时我们的编程一般都是同步编程,所谓同步编程的意思,和我们平时说的同时做几件事情完全不同. ...

  3. javascript中优雅的处理async和await异常

    let handler = async function(needErr) { return new Promise((resolve, reject) => { if (needErr) { ...

  4. 浅谈C#中常见的委托<Func,Action,Predicate>(转)

    一提到委托,浮现在我们脑海中的大概是听的最多的就是类似C++的函数指针吧,呵呵,至少我的第一个反应是这样的. 关于委托的定义和使用,已经有诸多的人讲解过,并且讲解细致入微,尤其是张子阳的那一篇.我就不 ...

  5. 浅谈async、await关键字 => 深谈async、await关键字

    前言 之前写过有关异步的文章,对这方面一直比较弱,感觉还是不太理解,于是会花点时间去好好学习这一块,我们由浅入深,文中若有叙述不稳妥之处,还请批评指正. 话题 (1)是不是将方法用async关键字标识 ...

  6. (译)关于async与await的FAQ

    传送门:异步编程系列目录…… 环境:VS2012(尽管System.Threading.Tasks在.net4.0就引入,在.net4.5中为其增加了更丰富的API及性能提升,另外关键字”async” ...

  7. 关于async与await的FAQ 转

    (译)关于async与await的FAQ 传送门:异步编程系列目录…… 环境:VS2012(尽管System.Threading.Tasks在.net4.0就引入,在.net4.5中为其增加了更丰富的 ...

  8. Ext JS学习第十六天 事件机制event(一) DotNet进阶系列(持续更新) 第一节:.Net版基于WebSocket的聊天室样例 第十五节:深入理解async和await的作用及各种适用场景和用法 第十五节:深入理解async和await的作用及各种适用场景和用法 前端自动化准备和详细配置(NVM、NPM/CNPM、NodeJs、NRM、WebPack、Gulp/Grunt、G

    code&monkey   Ext JS学习第十六天 事件机制event(一) 此文用来记录学习笔记: 休息了好几天,从今天开始继续保持更新,鞭策自己学习 今天我们来说一说什么是事件,对于事件 ...

  9. 第十五节:深入理解async和await的作用及各种适用场景和用法

    一. 同步VS异步 1.   同步 VS 异步 VS 多线程 同步方法:调用时需要等待返回结果,才可以继续往下执行业务 异步方法:调用时无须等待返回结果,可以继续往下执行业务 开启新线程:在主线程之外 ...

随机推荐

  1. Java -- 内部类(一)

    什么是内部类 将一个类的定义放在另一个类的定义内部,这就是内部类.在Java中内部类主要分为成员内部类.局部内部类.匿名内部类.静态内部类.举个栗子: public class A { public ...

  2. Dropping tests [POJ2976] [01分数规划]

    Description 今年有 n 场 ACM-ICPC 竞赛,小明每场都有资格参加.第 i 场竞赛共有 b[i] 道题.小明预测第 i场他能做出 a[i] 道题.为了让自己看着更“大佬”一些,小明想 ...

  3. 解释Eclipse下Tomcat项目部署路径问题(.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps)

    配置eclipse的开发环境,配置jdk的安装路径和tomcat安装路径.在eclipse下建立Dynamic Web Project工程zhgy,在使用eclipse中new一个tomcat,通过启 ...

  4. Linux之nginx反向代理三台web

    作业三:nginx反向代理三台web 实现基于轮询的方式调度三台web,并验证结果 实现基于权重的方式调度三台web,并验证结果 实现基于hash的方式调用三台web,并验证结果 [root@loca ...

  5. JS的document.anchors函数使用示例

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  6. jPlayer获取播放时间

    关于jPlayer的用法,可以参考:jPlayer 2.6.0开发者手册 http://www.jplayer.cn/developer-guide.html 视频播放例子: //视频播放 var v ...

  7. mvn -N和-U的用法

    mvn参数-N.-U理解 关于-N -N,--non-recursive Do not recurse into sub-projects 意思是,不递归到子项目(子模块). 举例: 一个父项目下Fa ...

  8. Office365 OneDrive Geo Move

    Issue Description: 1. Connect to SPO Service. 2. Validate SPO Service OneDrive Geo move compatibilit ...

  9. spring mvc \ spring boot 允许跨域请求 配置类

    用@Component 注释下,随便放个地方就可以了 package com.chinaws.wsarchivesserver.core.config; import org.springframew ...

  10. OHDSI——数据标准化

    Home › Data Standardization Data Standardization Data standardization is the critical process of bri ...