多线程(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是创建和控制 ...
随机推荐
- electron 打包后node_modules 体积过于庞大
问题产生原因:过多无用的模块被打包放入到程序中 解决: 删除 package-lock.json ,是由于这个文件导致打包时候放入过多文件,删除即可.
- django 标签的使用
首先重建一个common的app 然后创建__init__使common成为一个包 注意templatetags 名字使固定的 并在下面创建一个名字为fitter的过滤器 注册过滤器app htm ...
- Ajax验证用户名是否被注册
Ajax验证用户名是否被注册 var xmlHttp; function createXMLHttpRequest(){ // 创建XMLHttp请求对象 if(window.ActiveXObjec ...
- Shell语言
1.shell脚本规范以.sh结尾 2.运行 3.赋予权限,查询shell的执行过程 输出时间的 输出日历 输出一年的日历 修改语言 计算机 read –t 3 –p “1111111111” # ...
- ndk编译libx264生成库
编译脚本如下: TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86_64 function build_x26 ...
- Android APK 瘦身 - JOOX Music项目实战
导语 JOOX Music是腾讯海外布局的一个音乐产品,2014年发布以来已经成为5个国家和地区排名第一的音乐App.东南亚是JOOX Music的主要发行地区,由于JOOX Music所面对的市场存 ...
- PHP_DOC php文档结构及注解浏览
项目中的PHP文件比较多,为了方便查看,使用PHP写了个小工具,可查看PHP文件的所有类.函数 和特定注释. 显示PHP文件的 Class 和 Function 显示 /// 开头的注解 显示 /// ...
- 快速理解Token,Cookie,Session
在Web应用中,HTTP请求是无状态的.即:用户第一次发起请求,与服务器建立连接并登录成功后,为了避免每次打开一个页面都需要登录一下,就出现了cookie,Session. Cookie Cookie ...
- css清除浮动的3种方式
前言: 当不给父元素设置宽高时,父元素的宽高会被子元素的内容撑开.但当子元素设置浮动属性(float) 后, 子元素会溢出到父元素外,父元素的宽高也不会被撑开,这称之为“高度塌陷”.可以理解为使用浮动 ...
- 机器学习基石笔记:Homework #1 PLA&PA相关习题
原文地址:http://www.jianshu.com/p/5b4a64874650 问题描述 程序实现 # coding: utf-8 import numpy as np import matpl ...