前言

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

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

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

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

它有以下两个常用方法:

 public void SetException(Exception exception);

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

 public void SetResult(TResult result);

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

一、Task.Run(Action action)方法

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

         public static Task Run(Action action)
{
var tcs = new TaskCompletionSource<object>();
new Thread(() => {
try
{
action();
tcs.SetResult(null);
}
catch (Exception ex)
{
tcs.SetException(ex);
}
}){ IsBackground = true }.Start();
return tcs.Task;
}

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

测试代码如下:

             TaskEx.Run(() =>
{
Thread.Sleep();
Console.WriteLine("Just For Test.");
});

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

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

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

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

         public static Task<TResult> Run<TResult>(Func<TResult> function)
{
var tcs = new TaskCompletionSource<TResult>();
new Thread(() =>
{
try
{
tcs.SetResult(function());
}
catch (Exception ex)
{
tcs.SetException(ex);
}
})
{ IsBackground = true }.Start();
return tcs.Task;
}

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

测试代码如下:

             string result = TaskEx.Run(() =>
{
Thread.Sleep();
return "Just For Test.";
}).Result;
Console.WriteLine(result);

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

二、Task.Delay(int milliSeconds)方法

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

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

测试代码如下:

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

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

完整代码:

 using System;
using System.Threading;
using System.Threading.Tasks; namespace ConsoleApp
{
class Program
{
static void Main(string[] args)
{
//Task.Run(Action action)方法
TaskEx.Run(() =>
{
Thread.Sleep();
Console.WriteLine("Just For Test.");
}); //Task.Run<TResult>(Func<TResult> function)方法
string result = TaskEx.Run(() =>
{
Thread.Sleep();
return "Just For Test.";
}).Result;
Console.WriteLine(result); //Task.Delay(int milliSeconds)方法
TaskEx.Delay().Wait();
Console.WriteLine("Just For Test.");
Console.ReadKey();
}
}
class TaskEx
{
public static Task Run(Action action)
{
var tcs = new TaskCompletionSource<object>();
new Thread(() => {
try
{
action();
tcs.SetResult(null);
}
catch (Exception ex)
{
tcs.SetException(ex);
}
}){ IsBackground = true }.Start();
return tcs.Task;
}
public static Task<TResult> Run<TResult>(Func<TResult> function)
{
var tcs = new TaskCompletionSource<TResult>();
new Thread(() =>
{
try
{
tcs.SetResult(function());
}
catch (Exception ex)
{
tcs.SetException(ex);
}
})
{ IsBackground = true }.Start();
return tcs.Task;
}
public static Task Delay(int milliseconds)
{
var tcs = new TaskCompletionSource<object>();
var timer = new System.Timers.Timer(milliseconds) { AutoReset = false };
timer.Elapsed += delegate { timer.Dispose();tcs.SetResult(null); };
timer.Start();
return tcs.Task;
}
}
}

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

  1. .net4.0下 解决asp.net中“从客户端中检测到有潜在危险的Request.Form值”的错误

    asp.net 2.0 通常解决办法 方案一: 将.aspx文件中的page项添加ValidateRequest="false" ,如下: <%@ Page Validate ...

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

    原因:在安装Framework v4.0之后,再启用IIS,导致Framework没有完全安装 解决:开始->所有程序->附件->鼠标右键点击“命令提示符”->以管理员身份运行 ...

  3. NET4.5中的Task.Run及Task.Delay方法

  4. 关于把.net 2.0的项目升级到.net4.0遇到的一些问题

    进入公司实习的的第一个项目又是是一个升级项目.这次升级的是一个c/s架构的项目. 大致介绍一下这个项目的结构客户端采用winform+devexpress商业控件开发的,数据库是用的oracle数据库 ...

  5. IIS运行.NET4.0配置

    IIS运行.NET4.0配置 “/CRM”应用程序中的服务器错误.配置错误说明: 在处理向该请求提供服务所需的配置文件时出错.请检查下面的特定错误详细信息并适当地修改配置文件. 分析器错误消息: 无法 ...

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

    方法一.浏览器设置成兼容模式. 方法二.安装服务器版的.Net40的补丁.http://download.csdn.net/detail/5653325/6642051 方法三.点击VS的工具菜单-- ...

  7. .NET4.0 __doPostBack未定义

    方法一.浏览器设置成兼容模式. 方法二.安装服务器版的.Net40的补丁.http://download.csdn.net/detail/5653325/6642051 方法三.点击VS的工具菜单-- ...

  8. 细说.NET中的多线程 (三 使用Task)

    上一节我们介绍了线程池相关的概念以及用法.我们可以发现ThreadPool. QueueUserWorkItem是一种起了线程之后就不管了的做法.但是实际应用过程,我们往往会有更多的需求,比如如果更简 ...

  9. php中读取文件内容的几种方法。(file_get_contents:将文件内容读入一个字符串)

    php中读取文件内容的几种方法.(file_get_contents:将文件内容读入一个字符串) 一.总结 php中读取文件内容的几种方法(file_get_contents:将文件内容读入一个字符串 ...

随机推荐

  1. strstr_while模型

    #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string. ...

  2. 简单学C——第二天

                 控制结构(-) 相信大家对流程图肯定很熟悉.下面我将介绍的正是关于此方面的,c语言中,控制结构大体分为选择结构和循环结构. 一.选择结构:     先贴出一般用于选择结构的语 ...

  3. Servlet处理Cookie

    1.CGI:进程,servlet:线程 2.HttpServletResponse下的方法就没有get开头的,(PrintWriter)getWriter在ServletResponse下. 3.st ...

  4. 1、Window10 Electron 开发环境搭建

    1:首先安装nodejs C:\Users\yan>node -v v4.5.0 2:安装Electron C:\Users\yan>npm install --g electron-pr ...

  5. validationEngine[转]

    随笔- 31  文章- 0  评论- 40  validationEngine中文版 — jquery强大的表单验证插件   中文汉化版,官方只有英文的.同时根据中国国情修改了部分验证规则. 这个插件 ...

  6. Android 使用HttpClient方式提交GET请求

    public void httpClientGet(View view) { final String username = usernameEditText.getText().toString() ...

  7. ckeditor与ckfinder简单整合使用

    Ckeditor与ckfinder简单整合使用 功能:主要用来发送图文的email,图片上传到本地服务器,但是email的图片地址要写上该服务器的远程地址(图片地址:例如:http://www.bai ...

  8. SQL*Net more data to client

    The server process is sending more data/messages to the client. The previous operation to the client ...

  9. 【游戏框架】Phaser

    PhaserDesktop and Mobile HTML5 game framework Phaser Examples

  10. 分布式文件系统FastDFS安装与配置(单机)

    安装包如下:fastdfs-nginx-module_v1.16.tar.gzFastDFS_v5.05.tar.gzlibfastcommon-master.zipnginx-1.8.0.tar.g ...