经验大分享:Task的用法

简介: 经验大分享:Task的用法

Task用法记录总结

1.创建Task的3种方法

1.1new方式实例化一个Task,需要通过Start方法启动

Task task = new Task(() =>

{

Thread.Sleep(100);

Console.WriteLine($"hello, task1的线程ID为{Thread.CurrentThread.ManagedThreadId}");

});

task.Start();

task.Start方式,每个task都在不同的线程中

代码:

private static void Main(string【】 args)

{

Console.WriteLine("Hello, World!");

Task task1 = new Task(() =>

{

Console.WriteLine("task1 is running on a thread id {0}. Is thread pool thread: {1}",

Thread.CurrentThread.ManagedThreadId,

Thread.CurrentThread.IsThreadPoolThread);

});

Task task2 = new Task(() =>

{

Console.WriteLine("task2 is running on a thread id {0}. Is thread pool thread: {1}",

Thread.CurrentThread.ManagedThreadId,

Thread.CurrentThread.IsThreadPoolThread);

});

Task task3 = new Task(() =>

{

Console.WriteLine("task3 is running on a thread id {0}. Is thread pool thread: {1}",

Thread.CurrentThread.ManagedThreadId,

Thread.CurrentThread.IsThreadPoolThread);

});

//不在同一个线程

task1.Start();

task2.Start();

task3.Start();

//在同一个线程

//task1.RunSynchronously();

//task2.RunSynchronously();

//task3.RunSynchronously();

Task.WaitAll(task1,task2,task3);

}

View Code

task.RunSynchronously方式,每个任务都在同一个线程。task会阻塞主线程

task.Start方式,不会阻塞主线程

1.2Task.Factory.StartNew(Action action)创建和启动一个Task

Task task2 = Task.Factory.StartNew(() =>

{

Thread.Sleep(100);

Console.WriteLine($"hello, task2的线程ID为{Thread.CurrentThread.ManagedThreadId}");

});

创建后自动运行Task

1.3Task.Run(Action action)将任务放在线程池队列,返回并启动一个Task

Task task3 = Task.Run(() =>

{

Thread.Sleep(100);

Console.WriteLine($"hello, task3的线程ID为{Thread.CurrentThread.ManagedThreadId}");

});

创建后自动运行Task

2.Task的Wait/WaitAny/WaitAll方法

task.Wait() 表示等待task执行完毕

Task.WaitAll(Task【】 tasks) 表示只有所有的task都执行完成了再解除阻塞

private static void Main(string【】 args)

{

Console.WriteLine("start");

Task task1 = new Task(() =>

{

Thread.Sleep(1000);

Console.WriteLine("task1 is running on a thread id {0}//代码效果参考:http://www.ezhiqi.com/zx/art_3426.html . Is thread pool thread: {1}",

Thread.CurrentThread.ManagedThreadId,

Thread.CurrentThread.IsThreadPoolThread);

});

Task task2 = new Task(() =>

{

Thread.Sleep(2000);

Console.WriteLine("task2 is running on a thread id {0}. Is thread pool thread: {1}",

Thread.CurrentThread.ManagedThreadId,

Thread.CurrentThread.IsThreadPoolThread);

});

Task task3 = new Task(() =>

{

Thread.Sleep(3000);

Console.WriteLine("task3 is running on a thread id {0}. Is thread pool thread: {1}",

Thread.CurrentThread.ManagedThreadId,

Thread.CurrentThread.IsThreadPoolThread);

});

// 不在同一个线程

task1.Start();

task2.Start();

task3.Start();

Task.WaitAll(task1,task2,task3);

Console.WriteLine("task 1 2 3 end");

}

task1 等待1秒,task2等待2秒 task3等待3秒,使用WaitAll,则会等所有任务执行完毕之后才结束。

Task.WaitAny(Task【】 tasks) 表示只要有一个task执行完毕就解除阻塞

task1 等待1秒,task2等待2秒 ,task3等待3秒,使用WaitAny,只要有一个task结束,就结束阻塞。这里task最先结束

3.Task的延续操作(WhenAny/WhenAll/ContinueWith)

Task.WhenAll(task1, task2, task3).ContinueWith((t) => {

//dosomething

Console.WriteLine("task 1 2 3 all End");

});

当task完成后执行某些操作。

4.带返回值的Task

private static int Main(string【】 args)

{

//1.new方式实例化一个Task

Task[span style="color: rgba(0, 0, 255, 1)">intint

{

Thread.Sleep(100);

Console.WriteLine($"hello, task1的线程ID为{Thread.CurrentThread.ManagedThreadId}");

return 12;

});

task.Start();

int ret = task.Result;

task.Wait();

Console.WriteLine(ret);

//2.Task.Run

Task[span style="color: rgba(0, 0, 255, 1)">intint

{

Thread.Sleep(1000);

Console.WriteLine($"hello, task2的线程ID为{Thread.CurrentThread.ManagedThreadId}");

return 13;

});

int ret2 = task2.Result;

Console.WriteLine(ret2);

//3.Task.Factory.StartNew

Task[span style="color: rgba(0, 0, 255, 1)">int

{

Thread.Sleep(100);

Console.WriteLine($"hello, task3的线程ID为{Thread.CurrentThread.ManagedThreadId}");

return 14;

});

int ret3 = task3.Result;

Console.WriteLine(ret3);

return 0;

}

5.异步async awit

private static void Main(string【】 args)

{

Console.WriteLine("begin download");

Task task = download();

Console.WriteLine("end download");

}

static async Task[span style="color: rgba(0, 0, 255, 1)">int

{

Console.WriteLine("开始");

await Task.Run(() => { Thread.Sleep(2222); });

Console.WriteLine("结束");

return 666;

}

可以看到主线程退出了,但download异步方法还没结束。

深入理解异步:

一文说通C#中的异步编程 - 老王Plus - 博客园 (cnblogs.com)

相关文章
|
4月前
|
存储
向量化代码实践问题之Task<T>类中的on_completed函数是如何工作的
向量化代码实践问题之Task<T>类中的on_completed函数是如何工作的
|
6月前
|
Java C#
C#学习相关系列之多线程(七)---Task的相关属性用法
C#学习相关系列之多线程(七)---Task的相关属性用法
|
开发者
priority task2 实验过程|学习笔记
快速学习 priority task2 实验过程
101 0
priority task2 实验过程|学习笔记
|
运维 Prometheus Kubernetes
工作用Go: 异步任务怎么写6 | Asynq: 专业异步任务框架
工作用Go: 异步任务怎么写6 | Asynq: 专业异步任务框架
1914 0
工作用Go: 异步任务怎么写6 | Asynq: 专业异步任务框架
|
调度 开发者
priority task1 实验过程|学习笔记
快速学习 priority task1 实验过程
|
测试技术 数据库 图计算
软件测试面试题: think_time的作用是什么?
软件测试面试题: think_time的作用是什么?
167 0
|
测试技术 数据库 图计算
软件测试面试题:think_time的作用是什么?
软件测试面试题:think_time的作用是什么?
108 0
|
Java 程序员 开发者
|
Java Linux 程序员
Java的wait()、notify()学习三部曲之二:修改JVM源码看参数
线程同步相关的JVM源码分析系列之二,修改源码查看运行时的虚拟机参数
234 0
Java的wait()、notify()学习三部曲之二:修改JVM源码看参数
|
Java 中间件 程序员
面经手册 · 第20篇《Thread 线程,状态转换、方法使用、原理分析》
大部分考试考的,基本都是不怎么用的。例外的咱们不说😄 就像你做程序开发,尤其在RPC+MQ+分库分表,其实很难出现让你用一个机器实例编写多线程压榨CPU性能。很多时候是扔出一个MQ,异步消费了。如果没有资源竞争,例如库表秒杀,那么其实你确实很难接触多并发编程以及锁的使用。 但!凡有例外,比如你需要开发一个数据库路由中间件,那么就肯定会出现在一台应用实例上分配数据库资源池的情况,如果出现竞争就要合理分配资源。如此,类似这样的中间件开发,就会涉及到一些更核心底层的技术的应用。
243 0
面经手册 · 第20篇《Thread 线程,状态转换、方法使用、原理分析》