C#之Task&匿名方法
好久没有来这里转悠了,闲了这么段时间,今天又来到这里,给人一种很熟悉的感觉。
最近一直在一个改修项目上,看着别人写的框架,感觉自己突然什么也不会了。学习了几天框架,现在来讲讲自己的心得。
这个项目是一个Web项目,对于前台没有太多的要求,都是一些后台的数据库处理。项目中使用了很多存储过程。第一天这样的框架,就是感觉,类实在太多了,每一个存储过程都用一个类来抽成实体,上百成千个存储过程,让我实在着不到边际。一天看下来,发觉还好,只要细点心,还是可以过的。
第二天主要是看封装好的API,随便找了一个API,调试了下,看到Task<FXArrayList>.Factory.StartNew(action[i])这样一个东西后,自己就犯傻了,不知道该如何继续下去。找来找去才发现这里的action时候通过Func<FXArrayList>(()=>对象.excute(param)).看了这些东西之后,我有了一些眉目了,知道接下来该从何处去调查。
首先了这里用到了Lambda表达式,这个我之前也遇到过。说白了,就是利用委托来作为基础实现了。还有一个问题就是匿名方法。
等查看了些资料。于是自己来手动来实现了下。
首先明白几个东西Func<TResult>这里就是一个泛型,表名我匿名方法返回的类型。
Task就是一个多线程的表现形式而已。看明白了也就很简单。就是对内部的方法属性了解下就清楚了。
来看下面的一个小例子:以下例子就是介绍如何是用Lambda和Task类。
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 Student stu = new Student(); 6 List<Func<int>> lstFunc = new List<Func<int>>() { 7 new Func<int>(()=>stu.WriteMsg("Lambda No001")), 8 new Func<int>(()=>stu.WriteMsg("Lambda No002")), 9 new Func<int>(()=>stu.WriteMsg("Lambda No003")), 10 new Func<int>(()=>stu.WriteMsg("Lambda No004")), 11 new Func<int>(()=>stu.WriteMsg("Lambda No005")) 12 }; 13 List<int> lstResult = new FuncThread().StartNewRet(lstFunc); 14 15 foreach (int result in lstResult) 16 { 17 Console.WriteLine(result.ToString()); 18 } 19 20 Console.Read(); 21 } 22 } 23 24 public class Student 25 { 26 public int WriteMsg(string msg) 27 { 28 Console.WriteLine(msg); 29 // Thread.Sleep(100); 30 31 return int.Parse(msg.Substring(msg.Length - 1)); 32 } 33 } 34 public class FuncThread 35 { 36 public List<int> StartNewRet(List<Func<int>> lstFunc) 37 { 38 List<int> lstResult = new List<int>(); 39 40 Task<int>[] lstTask = new Task<int>[lstFunc.Count]; 41 42 for (int index = 0; index < lstFunc.Count; index++) 43 { 44 lstTask[index] = Task.Factory.StartNew<int>(lstFunc[index]); 45 // CheckTaskIsComplete(lstTask, index); 46 } 47 48 Task.WaitAll(lstTask); 49 50 // CheckTaskIsComplete(lstTask,10); 51 52 Console.WriteLine("Task Complete"); 53 54 for (int index = 0; index < lstTask.Length; index++) 55 { 56 lstResult.Add(lstTask[index].Result); 57 } 58 59 return lstResult; 60 } 61 } 62 }
在这个例子里面,我定义一个匿名方法集合。然后交由Task类进行处理。
代码很简单。我也不多说了啊。解释一点就是Task.WaitAll(params Task[])这个方法就是表名等我们所有的Task都结束了,才继续往下执行。Task中关于等待的方法还有其他几种,大家可以去查看MSDN就可以明白了啊。这里我就不多说了啊。
看看运行效果如何。
大家可以发现这里Task执行顺序是不是按顺序执行的。而是随机的。关于这点我很不明白。都是一样的代码,为什么会出现这样的现象。不过可以肯定的是这个Task类应该是分配多个线程去做。
于是我修改了下代码。加了点Log来看看到底怎么回事: 修改了下FuncThread这个类
public List<int> StartNewRet(List<Func<int>> lstFunc) { List<int> lstResult = new List<int>(); Task<int>[] lstTask = new Task<int>[lstFunc.Count]; for (int index = 0; index < lstFunc.Count; index++) { lstTask[index] = Task.Factory.StartNew<int>(lstFunc[index]); CheckTaskIsComplete(lstTask, index); } Task.WaitAll(lstTask); CheckTaskIsComplete(lstTask,10); Console.WriteLine("Task Complete"); for (int index = 0; index < lstTask.Length; index++) { lstResult.Add(lstTask[index].Result); } return lstResult; } private void CheckTaskIsComplete(Task<int>[] lstTask,int index) { Console.WriteLine(string.Format("==================第{0}回開始=======================\n", index + 1)); for (int i = 0; i < lstTask.Length; i++) { if (lstTask[i] != null) { Console.WriteLine(string.Format("\t==============第{0}個タスク状況:{1}",new string[]{(i+1).ToString(),lstTask[i].IsCompleted?"終了":"処理中"})); } } Console.WriteLine(string.Format("==================第{0}回終了=======================\n", index + 1)); }
从这里看来,Task组中的方法是依次执行的。到现在还是不了解到底是怎么来运行的。
如果有大神可以理解,麻烦帮我解决这个问题了啊。
对于使用这方面,我相信大家看了应该都明白了啊。如何去使用这样的这个匿名和Task类了啊。
很简单吧。