Task 实现多线程的模板

时间:2024-08-14 13:35:02

 

 

1.Task多线程简单模板

 

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Threading.Tasks;
  4. namespace Exercises
  5. {
  6.     public
    class GroupInfo
  7.     {
  8.         public
    string GroupId { get; set; }
  9.         public
    string Data { get; set; }
  10.     }
  11.     public
    class MutilTaskTemplate
  12.     {
  13.         //执行此方法,可以看到效果
  14.         public
    void Test()
  15.         {
  16.             Run();
  17.         }
  18.         public IEnumerable<GroupInfo> GetGroupInfos()
  19.         {
  20.             return
    new List<GroupInfo>() {
  21.                 new GroupInfo(){ GroupId = Guid.NewGuid().ToString(), Data = "what!"},
  22.                 new GroupInfo(){ GroupId = Guid.NewGuid().ToString(), Data = "hello!"},
  23.                 new GroupInfo(){ GroupId = Guid.NewGuid().ToString(), Data = "world!"},
  24.                 new GroupInfo(){ GroupId = Guid.NewGuid().ToString(), Data = "hehe!"}
  25.             };
  26.         }
  27.         public
    void Run()
  28.         {
  29.             Console.WriteLine("start!");
  30.             var groupInfos = GetGroupInfos();
  31.             List<Task> groupInfoTasks = new List<Task>();
  32.             foreach (var groupInfo in groupInfos)
  33.             {
  34.                 var task = new Task((inGroupInfo) =>
  35.                 {
  36.                     ForEveryGroup(inGroupInfo as GroupInfo);
  37.                 }, groupInfo);
  38.                 groupInfoTasks.Add(task);
  39.             }
  40.             Parallel.ForEach(groupInfoTasks, (t) => { t.Start(); });
  41.             Task.WaitAll(groupInfoTasks.ToArray());
  42.             Console.WriteLine("over!");
  43.         }
  44.         private
    void ForEveryGroup(GroupInfo groupInfo)
  45.         {
  46.             Console.WriteLine();
  47.             Console.WriteLine(groupInfo.GroupId);
  48.             //use the groupInfo.Data;
  49.             Console.WriteLine(groupInfo.Data);
  50.         }
  51.     }
  52. }

 

 

执行结果:

Task 实现多线程的模板

 

 

2.Task多线程带子线程模板

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Threading.Tasks;
  4. using System.Linq;
  5. namespace Exercises
  6. {
  7.     public
    class GroupInfo2
  8.     {
  9.         public
    string GroupId { get; set; }
  10.         public List<RealData> Datas { get; set; }
  11.     }
  12.     public
    class RealData
  13.     {
  14.         public RealData(string name, int age)
  15.         {
  16.             this.Name = name;
  17.             this.Age = age;
  18.         }
  19.         public
    string Name { get; set; }
  20.         public
    int Age { get; set; }
  21.     }
  22.     public
    class MutilTaskWithSubTaskTemplate
  23.     {
  24.         //执行此方法,可以看到效果
  25.         public
    void Test()
  26.         {
  27.             Run();
  28.         }
  29.         public IEnumerable<GroupInfo2> GetGroupInfos()
  30.         {
  31.             return
    new List<GroupInfo2>() {
  32.                 new GroupInfo2(){ GroupId = Guid.NewGuid().ToString(), Datas = new List<RealData>(){
  33.                     new RealData("daniu",26),new RealData("daniu2",27),new RealData("daniu3",28)} },
  34.                 new GroupInfo2(){ GroupId = Guid.NewGuid().ToString(), Datas = new List<RealData>(){
  35.                     new RealData("pzdn",26),new RealData("pzdn2",27)} },
  36.                 new GroupInfo2(){ GroupId = Guid.NewGuid().ToString(), Datas = new List<RealData>(){
  37.                     new RealData("pozi",26),new RealData("pozi2",27),new RealData("pozi3",28)} },
  38.                 new GroupInfo2(){ GroupId = Guid.NewGuid().ToString(), Datas = new List<RealData>(){
  39.                     new RealData("douzi",26),new RealData("douzi2",27),new RealData("douzi3",28)} }
  40.             };
  41.         }
  42.         public
    void Run()
  43.         {
  44.             Console.WriteLine("start!");
  45.             var groupInfos = GetGroupInfos();
  46.             int splitNumber = 2; //2条数据一个Task,改变此数值,则可以控制每条子线程的执行数据量
  47.             List<Task> groupInfoTasks = new List<Task>();
  48.             foreach (var groupInfo in groupInfos)
  49.             {
  50.                 var task = new Task((inGroupInfo) =>
  51.                 {
  52.                     int remainData = groupInfo.Datas.Count % splitNumber;
  53.                     int splits = groupInfo.Datas.Count / splitNumber + (remainData != 0 ? 1 : 0);
  54.                     var tmpGroupInfo = inGroupInfo as GroupInfo2;
  55.                     for (int i = 0; i < splits; i++)
  56.                     {
  57.                         bool flag = (i == splits - 1) && remainData != 0;
  58.                         //当前分组的子线程
  59.                         var subTask = new Task((inList) =>
  60.                         {
  61.                             ForEveryGroup(groupInfo.GroupId, inList as IEnumerable<RealData>);
  62.                         }, tmpGroupInfo.Datas.Skip(splitNumber * i).Take(flag ? remainData : splitNumber), TaskCreationOptions.AttachedToParent);
  63.                         subTask.Start();
  64.                     }
  65.                 }, groupInfo);
  66.                 groupInfoTasks.Add(task);
  67.             }
  68.             Parallel.ForEach(groupInfoTasks, (t) => { t.Start(); });
  69.             try
  70.             {
  71.                 Task.WaitAll(groupInfoTasks.ToArray());
  72.             }
  73.             catch (AggregateException e)  //AggregateException可以捕获运行中出现的错误
  74.             {
  75.                 Console.WriteLine("Caught Exception:" + e.InnerException.Message); //这里显示
  76.             }
  77.             Console.WriteLine("over!");
  78.         }
  79.         private
    void ForEveryGroup(string groupId, IEnumerable<RealData> realDatas)
  80.         {
  81.             Console.WriteLine(groupId);
  82.             //use the groupInfo.Data;
  83.             Console.WriteLine(realDatas == null);
  84.             foreach (var item in realDatas)
  85.             {
  86.                 Console.WriteLine(item.Name + "-" + item.Age);
  87.             }
  88.         }
  89.     }
  90. }

 

 

执行结果:

Task 实现多线程的模板

 

3.加入超时

可以增加一个等待超时的字段,在Task.WaitAll(groupInfoTasks.ToArray(),timeOut);