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
    评论
C# 中的 await 和 async 关键字用于实现异步编程模式。它们是一对关键字,用于简化异步代码的编写和管理。 关键字 async 用于修饰方法,表明该方法是一个异步方法。异步方法可以在执行过程中暂时挂起,允许其他代码在这个方法等待某些操作完成时继续执行。 关键字 await 用于等待一个异步操作的完成。它只能在异步方法内部使用,并且必须与返回类型为 TaskTask<T> 或类似的异步操作类型一起使用。当遇到 await 关键字时,方法将暂时挂起,直到等待的异步操作完成后再继续执行。 使用 await 和 async 的好处是简化了异步代码的编写和理解,使得异步操作更加直观和易于管理。它们可以帮助提高程序的响应性和性能,避免阻塞主线程。 下面是一个简单的示例,演示了如何使用 await 和 async: ```csharp public async Task<string> GetDataAsync() { // 模拟一个耗时的异步操作 await Task.Delay(1000); return "Data"; } public async Task Main() { Console.WriteLine("开始获取数据..."); string data = await GetDataAsync(); Console.WriteLine($"获取到的数据为: {data}"); } ``` 在上面的示例中,GetDataAsync 方法是一个异步方法,其中的 await 关键字会暂时挂起方法的执行,等待 Task.Delay 方法完成后再继续执行。在 Main 方法中,使用 await 关键字等待 GetDataAsync 方法的完成,并获取返回的数据。 希望以上解释对你有所帮助!如果还有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值