前言

.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. 小游戏 Lights Out (关灯) 的求解 —— 异或方程组

    Author : Evensgn  Blog Link : http://www.cnblogs.com/JoeFan/ Article Link : http://www.cnblogs.com/J ...

  2. 实验一个最小的PYTHON服务器编程

    没事,玩玩儿~~~:) 按书上的例子来作.. #!/usr/bin/env python #Simple Server - Chapter 1 -server.py import socket hos ...

  3. TEdit,TMemo背景透明

    The component below works perfectly, except for the following problem: 1) Saves the component below ...

  4. Unity 物体围绕圆周运动

    用Unity开发游戏中,经常会有搜寻的功能,这时候我们需要一个放大镜的图标在那圆周运动.写了相关脚本直接挂载在要圆周运动的物体上即可: using UnityEngine; using System. ...

  5. 传智播客C语言视频第一季(有效下载期为10.1-10.7,10.8关闭)

     J:\传智播客_尹成_C语言从菜鸟到高手├─传智播客_尹成_C语言从菜鸟到高手_第一章C语言概述A│      第一讲1.1C语言第一阶段.mp4│      第二讲1.2c语言入门教程.mp4 ...

  6. Linux学习笔记27——共享内存

    一 共享内存 共享内存是由IPC为进程创建的一个特殊的地址范围,它将出现在该进程的地址空间中.其他进程可以将同一段共享内存连接到它们自己的地址空间中,所有进程都可以访问共享内存中的地址.如果某个进程向 ...

  7. Scrapinghub | Professional Services

    VShell破解版 VShell破解版 Scrapinghub | Professional Services OUR PROFESSIONAL SERVICES INCLUDE

  8. JavaEE中遗漏的10个最重要的安全控制

    本文由码农网 – 小峰原创翻译,转载请看清文末的转载要求,欢迎参与我们的付费投稿计划! JavaEE有一些超赞的内置安全机制,但它们远远不能覆盖应用程序要面临的所有威胁.很多常见攻击,例如跨站点脚本攻 ...

  9. UVA 10106 (13.08.02)

     Product  The Problem The problem is to multiply two integers X, Y. (0<=X,Y<10250) The Input T ...

  10. kafka offset-check工具失效的问题

    转载请注明原创地址http://www.cnblogs.com/dongxiao-yang/p/5414077.html 由于平时业务预警等需求,针对现在公司的kafka系统部署了几套监控系统,包括调 ...