C# Task中的Func, Action, Async与Await的使用

时间:2021-12-13 09:14:26

在说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:(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:(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 }

执行功效如下:

C# Task中的Func, Action, Async与Await的使用

4. Async、Await

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