多线程(4)Task
使用线程池使得创建线程已经很简单了,但是使用线程池不支持线程的取消,完成和失败通知等交互操作,为了解决这些问题,.net 4.0带来了TPL(Task Parallel Library)任务并行库,下面就来总结下Task的使用。
创建和运行任务
在.net 4.0下使用task创建一个线程非常简单,有两种方式,如下代码:

namespace ConsoleApplication19
{
class Program
{
static void Main(string[] args)
{
//方法1
var task1 = new Task(() =>
{
Console.WriteLine("Create and start task!");
});
task1.Start(); //方法2
Task.Factory.StartNew(() =>
{
Console.WriteLine("Task factory start new task!");
}); Console.ReadKey();
}
}
}
输出结果:

需要注意的是:task也是基于线程池的,所以这两个任务的执行顺序是不固定的。
取消任务
创建一个新的任务之后,我们随时都可以取消它,取消方法如下代码:

namespace ConsoleApplication20
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Main thread starting..."); var cts = new CancellationTokenSource();
var task1 = Task.Factory.StartNew(() =>
{
TaskAction(cts.Token);
}); Thread.Sleep();
Console.WriteLine(string.Format("current task status::{0}", task1.Status)); //取消任务
cts.Cancel();
Console.WriteLine("start cancel task!");
for (int i = ; i < ; i++)
{
Thread.Sleep();
Console.WriteLine(string.Format("current task status::{0}", task1.Status));
} Console.WriteLine("Main thread completed!");
Console.ReadKey();
} public static void TaskAction(CancellationToken token)
{
Console.WriteLine("Sub thread starting..."); while (true)
{
Thread.Sleep();
if (token.IsCancellationRequested)
{
Console.WriteLine("Sub thread be cancelled!");
return;
}
Console.WriteLine("Sub thread is running!");
}
} }
}
输出结果:

创建任务集合并输出结果
如下代码:
namespace ConsoleApplication21
{
class Program
{
static void Main(string[] args)
{
//创建任务集合并输出结果
var tasks = new List<Task<string>>(); var task1 = Task.Factory.StartNew<string>(() =>
{
Console.WriteLine("task1 running on thread id:"+ Thread.CurrentThread.ManagedThreadId);
return "task1";
});
tasks.Add(task1); var task2 = Task.Factory.StartNew<string>(() =>
{
Console.WriteLine("task2 running on thread id:" + Thread.CurrentThread.ManagedThreadId);
return "task2";
});
tasks.Add(task2); var task3 = Task.Factory.StartNew<string>(() =>
{
Console.WriteLine("task3 running on thread id:" + Thread.CurrentThread.ManagedThreadId);
return "task3";
});
tasks.Add(task3); //输出结果
foreach (var item in tasks)
{
Console.WriteLine(item.Result);//调用Task的Result方法相当于调用了Task.WaitAll(tasks.ToArray());
} Console.ReadKey();
}
}
}
输出结果:

这里要注意2点:
1,每个任务会开启一个新的线程,并且运行顺序不固定。
2,Task.Result相当于调用了Wait方法,等待异步任务完成。
多任务的串行化
如下代码:
namespace ConsoleApplication22
{
class Program
{
static void Main(string[] args)
{
//多任务的串行化
var task1 = Task.Factory.StartNew(() =>
{
Console.WriteLine("start task1...");
Console.WriteLine("current thread id:"+ Thread.CurrentThread.ManagedThreadId);
}); var task2 = task1.ContinueWith((item) =>
{
Console.WriteLine("start task2...");
Console.WriteLine("current thread id:" + Thread.CurrentThread.ManagedThreadId);
}); var task3 = task2.ContinueWith((item)=>
{
Console.WriteLine("start task3...");
Console.WriteLine("current thread id:" + Thread.CurrentThread.ManagedThreadId);
}); Console.ReadKey();
}
}
}
输出结果:

注意,多任务串行化后,就相当于顺序执行了,而且有可能使用的是同一个线程,从上图的thread id就可以看出来。
多任务等待执行完成
如下代码:
namespace ConsoleApplication23
{
class Program
{
static void Main(string[] args)
{
//多任务等待执行完成
var tasks = new List<Task<string>>(); var task1 = Task.Factory.StartNew<string>(() =>
{
Console.WriteLine("task1");
return "task1";
});
tasks.Add(task1); var task2 = Task.Factory.StartNew<string>(() =>
{
Console.WriteLine("task2");
return "task2";
});
tasks.Add(task2); var task3 = Task.Factory.StartNew<string>(() =>
{
Console.WriteLine("task3");
return "task3";
});
tasks.Add(task3); //等待所有任务完成
Task.WaitAll(tasks.ToArray()); //等价于下面的调用
//foreach (var item in tasks)
//{
// item.Result
//} Console.ReadKey();
}
}
}
输出结果:

需要注意的是,如果是有返回值的task,可以使用Task.Result获取返回值的同时,也在等待Task执行完成,相当于调用了Task.Wait方法。
创建子任务
如下代码:
namespace ConsoleApplication24
{
class Program
{
static void Main(string[] args)
{
//创建子任务
var parentTask = Task.Factory.StartNew(() =>
{
Console.WriteLine("parent task!");
var childTask = Task.Factory.StartNew(() =>
{
Console.WriteLine("child task!");
}, TaskCreationOptions.AttachedToParent);
}); Console.ReadKey();
}
}
}
输出结果:

多线程(4)Task的更多相关文章
- 【多线程】 Task ,async ,await
[多线程]Task ,async ,await 一. WinForm 里经常会用到多线程, 多线程的好出就不多说了,来说说多线程比较麻烦的地方 1. UI 线程与其他线程的同步,主要是 Form 和 ...
- 【多线程】 Task
[多线程] Task 一. 常用方法: 1. ContinueWith : 当前 Task 完成后, 执行传入的 Task 2. Delay : 创建一个等待的 Task,只有在调用 Wait 方法时 ...
- .Net 多线程 (1) Task
多线程是一种有效提高程序工作效率的方法.当然为了效率需要使用更多的cpu,内存等资源. 并发是两个队列交替使用一台咖啡机,并行是两个队列同时使用两台咖啡机,如果串行,一个队列使用一台咖啡机,那么哪怕前 ...
- 【多线程】Task
介绍 Task是.NET推出数据任务处理的工作类.位于System.Threading.Tasks命名空间下,通过命名空间也可以看出是个多线程类. 创建Task: Task有很多构造函数,无参有参都有 ...
- C#多线程编程のTask(任务全面解析)
Task是.NET4.0加入的,跟线程池ThreadPool的功能类似,用Task开启新任务时,会从线程池中调用线程,而Thread每次实例化都会创建一个新的线程. 我们可以说Task是一种基于任务的 ...
- C# 应用 - 多线程 3) Task.Factory
1. 与 Task.Run() 的区别: 先看一下源码: public class Task : IThreadPoolWorkItem, IAsyncResult, IDisposable { pu ...
- C# 应用 - 多线程 4) Task cancel
1. 操作取消 1.1 步骤 实例化 CancellationTokenSource 对象,该对象管理取消通知并将其发送给单个取消标记 将 CancellationTokenSource.Token ...
- Task/Parallel实现异步多线程
代码: #region Task 异步多线程,Task是基于ThreadPool实现的 { //TestClass testClass = new TestClass(); //Action<o ...
- .NET多线程(Thread,ThreadPool,Task,Async与Await)
.NET多线程是什么? 进程与线程 进程是一种正在执行的程序. 线程是程序中的一个执行流. 多线程是指一个程序中可以同时运行多个不同的线程来执行不同的任务. .NET中的线程 Thread是创建和控制 ...
随机推荐
- [VUE]object.defineProperty的基本使用
1.object.defineProperty 给一个对象定义一个新的属性或者在修改一个对象现有的属性,并返回这个对象 语法: Object.defineProperty(参数1,参数2,参数3) 参 ...
- linux操作命令之搜索命令
1.文件搜索命令:locate 文件名 在后台数据库中按照文件名搜索,搜素速度更快 /var/lib/mlocate:#locate命令所搜索的后台数据库 updatedb:更新数据库 updated ...
- 在vue项目中mock数据
第一步:安装: 在命令行中执行: npm install mockjs; 第二步:定义index.js文件 我们新建一个mock文件夹,此文件夹中建一个index.js文件:在index.js中输入以 ...
- NodeJS NPM 镜像使用方法
每次npm的时候,走国外的镜像,非常的慢,可以配置一下 通过改变默认npm镜像代理服务,以下三种办法任意一种都能解决问题,建议使用第三种,将配置写死,下次用的时候不用重新配置. 通过config命令 ...
- Data Center(5): 实例
我们来分析从外网访问内网的服务的具体过程: 首先我们看DNS和Load Balancer是怎么工作的. 客户端要访问我们的系统,发送了一个https请求,https://nova.mycompany. ...
- Xtrabackup实现Mysql的InnoDB引擎热备份
前面Zabbix使用的数据库是mysql,数据库备份不用多说,必须滴,由于使用的是innodb引擎,既然做,那就使用第三方强大的Xtrabackup工具来热备吧,Xtrabackup的说明,参见htt ...
- PHP_DOC php文档结构及注解浏览
项目中的PHP文件比较多,为了方便查看,使用PHP写了个小工具,可查看PHP文件的所有类.函数 和特定注释. 显示PHP文件的 Class 和 Function 显示 /// 开头的注解 显示 /// ...
- SUSE12Sp3-kafka安装
1.安装java jdk sudo mkdir -p /usr/local/java #创建目录 将jdk-8u201-linux-x64.tar.gz上传到该目录 cd /user/local/ja ...
- [Swift]LeetCode391. 完美矩形 | Perfect Rectangle
Given N axis-aligned rectangles where N > 0, determine if they all together form an exact cover o ...
- [Swift]LeetCode581. 最短无序连续子数组 | Shortest Unsorted Continuous Subarray
Given an integer array, you need to find one continuous subarray that if you only sort this subarray ...