.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属性提供对使用者方的访问。
它有以下两个常用方法:
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方法的更多相关文章
- .net4.0下 解决asp.net中“从客户端中检测到有潜在危险的Request.Form值”的错误
asp.net 2.0 通常解决办法 方案一: 将.aspx文件中的page项添加ValidateRequest="false" ,如下: <%@ Page Validate ...
- Win2008上.NET4.0部署出错HTTP 错误 500.21 - Internal Server Error的解决方法
原因:在安装Framework v4.0之后,再启用IIS,导致Framework没有完全安装 解决:开始->所有程序->附件->鼠标右键点击“命令提示符”->以管理员身份运行 ...
- NET4.5中的Task.Run及Task.Delay方法
- 关于把.net 2.0的项目升级到.net4.0遇到的一些问题
进入公司实习的的第一个项目又是是一个升级项目.这次升级的是一个c/s架构的项目. 大致介绍一下这个项目的结构客户端采用winform+devexpress商业控件开发的,数据库是用的oracle数据库 ...
- IIS运行.NET4.0配置
IIS运行.NET4.0配置 “/CRM”应用程序中的服务器错误.配置错误说明: 在处理向该请求提供服务所需的配置文件时出错.请检查下面的特定错误详细信息并适当地修改配置文件. 分析器错误消息: 无法 ...
- .Net4.0的网站在IE10、IE11出现“__doPostBack未定义”的解决办法。
方法一.浏览器设置成兼容模式. 方法二.安装服务器版的.Net40的补丁.http://download.csdn.net/detail/5653325/6642051 方法三.点击VS的工具菜单-- ...
- .NET4.0 __doPostBack未定义
方法一.浏览器设置成兼容模式. 方法二.安装服务器版的.Net40的补丁.http://download.csdn.net/detail/5653325/6642051 方法三.点击VS的工具菜单-- ...
- 细说.NET中的多线程 (三 使用Task)
上一节我们介绍了线程池相关的概念以及用法.我们可以发现ThreadPool. QueueUserWorkItem是一种起了线程之后就不管了的做法.但是实际应用过程,我们往往会有更多的需求,比如如果更简 ...
- php中读取文件内容的几种方法。(file_get_contents:将文件内容读入一个字符串)
php中读取文件内容的几种方法.(file_get_contents:将文件内容读入一个字符串) 一.总结 php中读取文件内容的几种方法(file_get_contents:将文件内容读入一个字符串 ...
随机推荐
- C语言-06数据类型-05 总结
一.基本数据类型1.int1> long int.long:8个字节 %ld2> short int.short:2个字节 %d %i3> unsigned int.unsigned ...
- css的继承、层叠和特殊性
1,继承 css的某些样式是具有继承性的,那么什么是继承呢?继承是一种规则,它允许样式不仅应用于某个特定html标签元素,而且应用于其后代. 但注意有一些css样式是不具有继承性的.如border: ...
- GO语言中的指针
http://www.tizgrape.com/?p=100 Go语言中的指针语法和C++一脉相承,都是用*作为符号,虽然语法上接近,但是实际差异不小. Go使用var定义变量: var v6 *in ...
- bzoj 2631: tree 动态树+常数优化
2631: tree Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 1716 Solved: 576[Submit][Status] Descrip ...
- 【LA2796】Concert Hall Scheduling(最大费用最大流)
Description You are appointed director of a famous concert hall, to save it from bankruptcy. The hal ...
- win7 热点设置命令
netsh wlan set hostednetwork mode=allownetsh wlan set hostednetwork ssid=XXXX key=XXXnetsh wlan star ...
- Guava学习
Guava学习笔记目录 Guava 是一个 Google 的基于java1.6的类库集合的扩展项目,包括 collections, caching, primitives support, concu ...
- iPhone之Quartz 2D系列--图形上下文(2)(Graphics Contexts)
以下几遍关于Quartz 2D博文都是转载自:http://www.cocoachina.com/bbs/u.php?action=topic&uid=38018 iPhone之Quartz ...
- ECC内存
ECC内存,即应用了能够实现错误检查和纠正技术(ECC)的内存条.一般多应用在服务器及图形工作站上,这将使整个电脑系统在工作时更趋于安全稳定.ECC是“Error Checking and Corre ...
- bzoj2002
这道题学习了一种简洁的解决一些数据结构题的方法——分块法这道题方法很多,但分块写起来只有1kb左右,非常的简洁(但不是非常的高效)首先很容易思考到一种暴力的做法,从后往前推,很容易搞出每个点会弹几次弹 ...