CSharp Task理解

Task是不同于Thread的。

个人理解
Task是对ThreadPool 池化线程更高的封装,具有更多的API可以供我们进行调用。

Task通俗一点将:我(Program)将会在未来的某个时间完成你给我的工作。

//Task接受一个委托。
public Task (Action action);

//The work to execute asynchronously
//工作会异步的进行执行
//接受一个Action无返回值的委托。
public static Task Run (Action action);

比如一个例子 -> 我接了一个私活儿,我需要进行如下的工作:

  1. 沟通需求
  2. 设计功能
  3. 谈价格
  4. 50%的前期开发费
  5. 开发项目
  6. 交接项目,收尾款

在第五步的时候,项目团队可以同时进行多个功能模块进行开发。

//开发Coding函数
private static void Coding(string name, string projectName)
{
	Console.Write($"功能开发人员 ->{name},当前项目名称 ->{projectName},当前工作线程 ->{Thread.CurrentThread.ManagedThreadId}");        
}
  • Main函数:
Console.WriteLine("开始进行沟通!*******************");
Console.WriteLine("开始进行设计");
Console.WriteLine("开始进行分配人员干活。");
Task.Run(() =>
{
   Coding("Leo", "DataBAse");
})
Task.Run(() =>
{
   Coding("Aaron", "UI");
})
Task.Run(() =>
{
   Coding("Tom", "WebApi");
})
Console.WriteLine("项目结束,收工。");

此处会产生一个问题,因为线程是异步的。执行的过程可能是:

  1. 沟通
  2. 设计
  3. 干活
  4. 手工
  5. 开发

因此我们需要使用 Task.WaitAll(param [] Task) 在程序有些地方进行异步执行。它接收一个 Task数组。
Task.WaitAll(param [] Task)<阻塞线程>代表所有的Task都执行完毕才能执行下面的语句。
Task.WaitAny(param [] Task) <阻塞线程>代表任意一个Task完成,就执行下面的语句。
让我们改造一下Main函数的代码。

Console.WriteLine("开始进行沟通!*******************");
Console.WriteLine("开始进行设计");
Console.WriteLine("开始进行分配人员干活。");
List<Task> tasks = new List<Task>();
tasks.Add(Task.Run(() =>
{
  Coding("Leo", "DataBAse");
}));
tasks.Add(Task.Run(() =>
{
  Coding("Aaron", "UI");
}));
tasks.Add(Task.Run(() =>
{
  Coding("Tom", "WebApi");
}));
Task.WaitAll(tasks.ToArray());
Console.WriteLine("项目结束,收工。");

但是又会产生一个问题,Task.WaitAll()会产生阻塞,那如果我们在做form窗体或者做web处理请求时改怎么处理呢。如果产生了阻塞,我们的form窗体就没办法拖动。web处理请求进来必须等待Task完成才能做别的事情。所以我们还需要再优化一下Main函数。

Console.WriteLine("开始进行沟通!*******************");
Console.WriteLine("开始进行设计");
Console.WriteLine("开始进行分配人员干活。");

//在这里用一个新的线程去跑。
Task.Run(()=>{
  List<Task> tasks = new List<Task>();
  tasks.Add(Task.Run(() =>
  {
      Coding("Leo", "DataBAse");
  }));
  tasks.Add(Task.Run(() =>
  {
      Coding("Aaron", "UI");
  }));
  tasks.Add(Task.Run(() =>
  {
      Coding("Tom", "WebApi");
  }));
  Task.WaitAll(tasks.ToArray());
  Console.WriteLine("项目结束,收工。");
});

但是个人不推荐。在开发中,我们尽量不要线程套线程。
我们有更优秀的封装。


TaskFactory tf = new TaskFactory();
//任意一个线程完成后,执行里面的过程
tf.ContinueWhenAny(tasks.ToArray() , t=>{
	//todoSometing
});
//所有线程完成后,执行里面的过程
tf.ContinueWhenAll(tasks.ToArray(),t=>{
	//todoSometing
});
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值