.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 }
作者:CNXY Github:https://www.github.com/cnxy 出处:http://cnxy.me 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 如果文中有什么错误,欢迎指出,谢谢! |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 智能桌面机器人:用.NET IoT库控制舵机并多方法播放表情
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 手把手教你在本地部署DeepSeek R1,搭建web-ui ,建议收藏!
· 新年开篇:在本地部署DeepSeek大模型实现联网增强的AI应用
· Janus Pro:DeepSeek 开源革新,多模态 AI 的未来
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(三):用.NET IoT库
· 【非技术】说说2024年我都干了些啥