zoukankan      html  css  js  c++  java
  • Task三个列子的分享

    这次要分享的是C#Task任务的几个列子,感觉最实用的是封装的分页任务执行方法,这个方法步奏也是目前在我工作中执行多任务常用的,不知道各位也有这用的情况,那么开始吧。

    1.顺序任务执行

     1 //顺序任务执行
     2             Task.Factory.StartNew<int>(() => { Console.WriteLine(1); return 1; }).
     3                 //等待5s以后才会依次输出2,3
     4                  ContinueWith((task) =>
     5                  {
     6 
     7                      Stopwatch wt = new Stopwatch();
     8                      wt.Start();
     9                      Thread.Sleep(1000 * 5);
    10                      wt.Stop();
    11                      Console.WriteLine("等待了:{0}ms,输出结果{1}", wt.ElapsedMilliseconds, 2);
    12                  }).
    13                  ContinueWith((task) => { Console.WriteLine(3); }).
    14                  Wait();
    View Code

      上面的代码中也备注了一些文字说明,其中有关键词语及意思如下:

      .Task.Factory.StartNew:创建一个Task实例,创建后自动开启,无需在调用Start;

      .ContinueWith:看单词的意思就明了,是继续的意思,在这里的效果也是等待上一个Task执行完毕了在继续执行本次任务,这里方法里面每个任务是一层一层传递的

      效果图:

      

      这里有个地方注意,sleep这是了5s但是这里使用Stopwatch统计出来只有4999ms,这个地方存在差异性,本章不解释,有兴趣朋友可以分享下或研究下。

      2.并行任务效果

     1 //并行任务
     2             var watch = new Stopwatch();
     3             //func方法(认知特点:任意长度参数,最后一个的类型是方法返回的返回值类型)
     4             Func<object, int> fun = (num) =>
     5             {
     6                 Thread.Sleep(1000 * 2);
     7                 Console.WriteLine("第{0}个", num);
     8                 return Convert.ToInt32(num);
     9             };
    10             var len = 5;
    11             var tasks = new Task<int>[len];
    12             //开始计算处理时间
    13             watch.Start();
    14             for (int _i = 0; _i < len; _i++)
    15             {
    16                 //Task.Factory.StartNew直接开启Task任务无需在使用start
    17                 tasks[_i] = Task.Factory.StartNew<int>(fun, _i);
    18             }
    19             //10s等待
    20             Task.WaitAll(tasks, 1000 * 10);
    21             watch.Stop();
    22             Console.WriteLine("tasks共使用时间:{0}s={1}ms", watch.ElapsedMilliseconds / 1000, watch.ElapsedMilliseconds);
    View Code

      关键词语及意思如下:

      .Func<object, int>这个是C#新增的特性,这个和Action最大的区别就是Func有返回值,其他的和Action相同任意长度参数个数和类型

      .Task.WaitAll这个方法有几个重载,这里用的是一个超时时间的方法,设置时间后在规定的时间就不继续等待Task【】了,如果task【】在超时时间范围内就执行完了,那么直接通过,不用再等待超时时间

      效果:

      

    这里依然有统计时间查问题,忽略

     

    3.分页任务执行方法

     1 /// <summary>
     2         /// 批次任务执行方法
     3         /// </summary>
     4         /// <typeparam name="T">参数类型</typeparam>
     5         /// <param name="func">func方法</param>
     6         /// <param name="list">待执行数据</param>
     7         /// <param name="taskLen">任务量</param>
     8         /// <param name="timeOut">任务超时时间 默认30s</param>
     9         /// <returns></returns>
    10         public static int _ExcuteTask<T>(Func<List<T>, int> func, List<T> list, int taskLen = 10, int timeOut = 30) where T : class
    11         {
    12             var result = 0;
    13             //任务量
    14             var tasks = new Task<int>[taskLen];
    15             var page = list.Count / taskLen + (list.Count % taskLen > 0 ? 1 : 0);  //每个分得得需要执行的总条数 最有一个执行剩余所有
    16             for (var ji = 1; ji <= taskLen; ji++)
    17             {
    18                 //使用分页方法获取待执行数据
    19                 var list01 = list.Skip((ji - 1) * page).Take(page).ToList();
    20                 if (list01.Count <= 0) { break; }
    21                 var task = Task.Run(() =>
    22                 {
    23 
    24                     return func(list01);
    25                 });
    26                 tasks[ji - 1] = task;
    27             }
    28             //等待执行
    29             Task.WaitAll(tasks, 1000 * 1 * timeOut);
    30             //获取执行成功条数
    31             result = tasks.Where(b => b.IsCompleted).Sum(b => b.Result);
    32 
    33             return result;
    34         }
    View Code

      测试代码:

     1 /// <summary>
     2         /// 测试执行底层数据方法
     3         /// </summary>
     4         /// <param name="list"></param>
     5         /// <returns></returns>
     6         static int _FuncTest(List<string> list)
     7         {
     8 
     9             foreach (var item in list)
    10             {
    11                 Thread.Sleep(1000 * 2);
    12                 Console.WriteLine("TaskId:{1}输出第{0}个值", item, Task.CurrentId);
    13             }
    14             return list.Count;
    15         }
    View Code
     1 //分页任务执行方法
     2             var listT = new List<string>();
     3             for (int _i = 0; _i < 9; _i++)
     4             {
     5                 listT.Add(_i.ToString());
     6             }
     7             watch.Restart();
     8             //调用任务公共方法
     9             var result = _ExcuteTask(_FuncTest, listT, 3);
    10             watch.Stop();
    11             Console.WriteLine("待处理数据:{0}条,共处理成功数据:{1}条,使用时间:{2}ms", listT.Count, result, watch.ElapsedMilliseconds);
    View Code

      这里使用的是分页的原理,把参数集合分发到创建的Task中,使用Task【】来处理这些数据,这里和第二个例子有点相识就多了分页写法而已,最后统计执行成功的条数,以此来返回给调用者,方便记录日志,此方法目前是我经常使用的,不知道是否还有更好的,各位多多分享,谢谢。

      效果图:

      

      以上就是这次的总结,希望多同学们有些帮助,有疑问或者问题请及时相互交流。

  • 相关阅读:
    添加绝对路径的链接
    css-------------控制溢出隐藏 换行用省略号表示
    引入公共头部 脚部
    入口图片放在浏览器正中间,点击之后缩小固定在浏览器一侧
    伪类 统一添加样式
    nav 鼠标移入当前高亮显示,其他消失
    17/9/6 bootstrap.css去掉后引发的样式错乱
    JavaScript的常见兼容问题及相关解决方法(chrome/IE/firefox)
    javascript特效实现——当前时间和倒计时效果
    使用DataTables导出excel表格
  • 原文地址:https://www.cnblogs.com/wangrudong003/p/5523984.html
Copyright © 2011-2022 走看看