.Net4.0如何实现.NET4.5中的Task.Run及Task.Delay方法

前言

.NET4.0下是没有Task.Run及Task.Delay方法的,而.NET4.5已经实现,对于还在使用.NET4.0的同学来说,如何在.NET4.0下实现这两个方法呢?

在.NET4.0下,有一个泛型类,叫TaskCompletionSource<TReuslt>,它能控制Task的行为,如给Task设置结果、设置异常、设置取消等。

MSDN是这样描述的(网址):

表示未绑定到委托的 Task<TResult> 的制造者方,并通过Task属性提供对使用者方的访问。

它有以下两个常用方法:

1 public void SetException(Exception exception);

当执行的任务有异常时,可以使用该方法是设置任务的异常。

1 public void SetResult(TResult result);

这是给任务设置一个返回值,如果任务没有返回值,直接设置null即可。

一、Task.Run(Action action)方法

该方法实现与Task.Factory.StartNew(Action action)类似,实现代码如下:

 1         public static Task Run(Action action)
 2         {
 3             var tcs = new TaskCompletionSource<object>();
 4             new Thread(() => {
 5                 try
 6                 {
 7                     action();
 8                     tcs.SetResult(null);
 9                 }
10                 catch (Exception ex)
11                 {
12                     tcs.SetException(ex);
13                 }
14             }){ IsBackground = true }.Start();
15             return tcs.Task;
16         }

该方法的目的是用来执行委托action所代表的方法,并返回当前所表示的任务,因方法的签名返回值类型为Task,所以需给tcs的SetResult方法设置一个null值。

测试代码如下:

1             TaskEx.Run(() =>
2             {
3                 Thread.Sleep(5000);
4                 Console.WriteLine("Just For Test.");
5             });

该代码的功能是在5s后输出“Just For Test”字符串到控制台。

注:TaskEx是用来封装Run静态方法的一个类,以下内容相同。

二、Task.Run<TResult>(Func<TResult> function)方法

该方法是Task.Run(Action action)的泛型版本,实现如下:

 1         public static Task<TResult> Run<TResult>(Func<TResult> function)
 2         {
 3             var tcs = new TaskCompletionSource<TResult>();
 4             new Thread(() =>
 5             {
 6                 try
 7                 {
 8                     tcs.SetResult(function());
 9                 }
10                 catch (Exception ex)
11                 {
12                     tcs.SetException(ex);
13                 }
14             })
15             { IsBackground = true }.Start();
16             return tcs.Task;
17         }

与Task.Run的非泛型版本类似,该方法的目的是用来执行委托function所代表的方法,并返回当前所表示的任务,该任务类型为Task<TResut>,带有Task的返回值。

测试代码如下:

1             string result = TaskEx.Run(() =>
2             {
3                 Thread.Sleep(5000);
4                 return "Just For Test.";
5             }).Result;
6             Console.WriteLine(result);

该方法的功能与上面的例子一样:在5s后输出“Just For Test”字符串到控制台,但其实现方式不一样,一个用的是Action委托,另外一个使用的是Function<TResult>委托。

二、Task.Delay(int milliSeconds)方法

1         public static Task Delay(int milliseconds)
2         {
3             var tcs = new TaskCompletionSource<object>();
4             var timer = new System.Timers.Timer(milliseconds) { AutoReset = false };
5             timer.Elapsed += delegate { timer.Dispose();tcs.SetResult(null); };
6             timer.Start();
7             return tcs.Task;
8         }

以上代码功能使用了System.Timers.Timer类来实现任务的延时,用来在milliSeconds毫秒后返回当前任务,该方法并不会阻塞人任何线程。

测试代码如下:

1             TaskEx.Delay(5000).Wait();
2             Console.WriteLine("Just For Test.");

该方法的功能还是与前面的两个一样,在5s后输出“Just For Test”字符串到控制台。

完整代码:

 1 using System;
 2 using System.Threading;
 3 using System.Threading.Tasks;
 4
 5 namespace ConsoleApp
 6 {
 7     class Program
 8     {
 9         static void Main(string[] args)
10         {
11             //Task.Run(Action action)方法
12             TaskEx.Run(() =>
13             {
14                 Thread.Sleep(5000);
15                 Console.WriteLine("Just For Test.");
16             });
17
18             //Task.Run<TResult>(Func<TResult> function)方法
19             string result = TaskEx.Run(() =>
20             {
21                 Thread.Sleep(5000);
22                 return "Just For Test.";
23             }).Result;
24             Console.WriteLine(result);
25
26             //Task.Delay(int milliSeconds)方法
27             TaskEx.Delay(5000).Wait();
28             Console.WriteLine("Just For Test.");
29             Console.ReadKey();
30         }
31     }
32     class TaskEx
33     {
34         public static Task Run(Action action)
35         {
36             var tcs = new TaskCompletionSource<object>();
37             new Thread(() => {
38                 try
39                 {
40                     action();
41                     tcs.SetResult(null);
42                 }
43                 catch (Exception ex)
44                 {
45                     tcs.SetException(ex);
46                 }
47             }){ IsBackground = true }.Start();
48             return tcs.Task;
49         }
50         public static Task<TResult> Run<TResult>(Func<TResult> function)
51         {
52             var tcs = new TaskCompletionSource<TResult>();
53             new Thread(() =>
54             {
55                 try
56                 {
57                     tcs.SetResult(function());
58                 }
59                 catch (Exception ex)
60                 {
61                     tcs.SetException(ex);
62                 }
63             })
64             { IsBackground = true }.Start();
65             return tcs.Task;
66         }
67         public static Task Delay(int milliseconds)
68         {
69             var tcs = new TaskCompletionSource<object>();
70             var timer = new System.Timers.Timer(milliseconds) { AutoReset = false };
71             timer.Elapsed += delegate { timer.Dispose();tcs.SetResult(null); };
72             timer.Start();
73             return tcs.Task;
74         }
75     }
76 }
时间: 2024-10-10 05:37:07

.Net4.0如何实现.NET4.5中的Task.Run及Task.Delay方法的相关文章

Win2008上.NET4.0部署出错HTTP 错误 500.21 - Internal Server Error的解决方法

原因:在安装Framework v4.0之后,再启用IIS,导致Framework没有完全安装 解决:开始->所有程序->附件->鼠标右键点击“命令提示符”->以管理员身份运行,输入以下命令: %windir%\\Microsoft.NET\\Framework\\v4.0.30319\\aspnet_regiis.exe -i 如果出现错误提示“aspnet_regiis.exe 不是有效的Win32应用程序”,可能是因为你的aspnet_regiis.exe损坏了. 去c:\w

.NET4.0 __doPostBack未定义

方法一.浏览器设置成兼容模式. 方法二.安装服务器版的.Net40的补丁.http://download.csdn.net/detail/5653325/6642051 方法三.点击VS的工具菜单-->库程序包管理器-->程序包管理器控制台(如果没有“库程序包管理器”的菜单,就先点那个“扩展管理器”,安装一个叫“NuGet程序包管理器”,然后就会有了.),点击后下面会出现一个连接PowerShell的控制台,等控制台加载完毕后输入 install-package App_BrowsersUpd

Net4.0的网站在IE10、IE11出现“__doPostBack未定义”的解决办法。

方法一.浏览器设置成兼容模式. 方法二.安装服务器版的.Net40的补丁.http://download.csdn.net/detail/5653325/6642051 方法三.点击VS的工具菜单-->库程序包管理器-->程序包管理器控制台(如果没有“库程序包管理器”的菜单,就先点那个“扩展管理器”,安装一个叫“NuGet程序包管理器”,然后就会有了.),点击后下面会出现一个连接PowerShell的控制台,等控制台加载完毕后输入 install-package App_BrowsersUpd

Asp.Net4.0/VS2010新变化(3):webform中也可以直接url路由

以前在做asp的时候,要把 /default.asp?id=123映射成/default/123,需要借助IISRewriter这个组件,到了asp.net以后,可以用代码写了,但是个人觉得很麻烦,要写一堆代码,还要修改web.config,现在好了:asp.net4.0中 asp.net mvc中的路由规则全部可以用于webform了 使用步骤: 1.Global.ascx.cs中先注册路由规则 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

NET4.0中非常好用的一个东西Tuple

最近发现了.NET4.0中一个非常好用的东西Tuple,自从知道了它之后,发现我的代码里面到处都是它的身影.那么Tuple究竟是何物呢? 在知道Tuple之前,我经常碰到要使用一些记录的集合,如果每条记录只有一个元素,一般都是用List来存储,如果每条记录,我想记录两个属性,我一般用Dictionary<int,int>来存储,但是如果每个记录要记录三个属性,甚至四个属性的时候,那么我们只能定义一个数据结构或者实体类来进行存储,然后再把这个实体装到List中去.但是大多数时候,这么一个List

&lt;pages validateRequest=&quot;false&quot;/&gt;在.net4.0中无效的问题

再web.config中设置<pages validateRequest="false"/>在.net4.0中无效的问题 解决方案: <system.web> <httpRuntime requestValidationMode="2.0"/> <pages validateRequest="false"/> </system.web> 新增<httpRuntime request

如何在.net4.0中使用.net4.5的async/await

推荐文章: http://www.cnblogs.com/hj4444/p/3857771.html http://www.cnblogs.com/dozer/archive/2012/03/06/async-and-await-in-web-application.html 一般喜欢学习新技术的同学都用过.net4.5吧,那肯定会被简单.高效的异步编程模型所吸引吧. 去年微软发布了Microsoft.Bcl.Async,该包由三个库组成:Microsoft.Bcl.Microsoft.Bcl.

[C#] .NET4.0中使用4.5中的 async/await 功能实现异步

在.NET Framework 4.5中添加了新的异步操作库,但是在.NET Framework 4.0中却无法使用.这时不免面临着抉择,到底是升级整个解决方案还是不使用呢? 如果你的软件还没发布出去,建议直接使用.NET Framework 4.5吧:但是如果已经发布了,又不想用户重新升级框架到.NET Framework 4.5,那也有一个办法,那就是使用库:Microsoft.Bcl.Async 在4.5中使用async/await 的地方如下: 好处呢,我不多说,我想说的是: What

iis6下配置支持.net4.0&amp;发布网站[转]

iis6配置支持.net4.0 在win2003操作系统上发布两个网站,首先配置iis: 1.下载 .net framework 4.0   差不多48MB 2.安装 3.打开iis: 开始=>管理工具=>Internet 信息服务(IIS)管理器 4.点击管理器中的“web服务扩展”,刚刚安装的.net framework 4.0 就会出现在右边,选择并允许 这样就配置好了 有时还要同时配置.net framework 3.5和.net framework 4.0 才可以,那就再配置一次3.