多线程(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是创建和控制 ...
随机推荐
- MVC Web.Config 配置错误
配置一个MVC项目的 SessionState,查阅了大量的资料,发现都是直接在web.config中直接加入类似的语句就可以了 <sessionState timeout="60&q ...
- python—迭代器、生成器
1.迭代器(iteration) 迭代器协议:提供next()方法,该方法要么返回迭代的下一项,要么异常.(只能往后走) 可迭代对象:实现迭代器协议的对象. **字符串.列表.元祖.字典.集合.文件都 ...
- ML-Framework:ML.NET 0.3 带来新组件
ML.NET在今年微软在Build 2018 会议上宣布的机器学习框架现已正式推出0.3版本 https://github.com/dotnet/machinelearning/releases/ta ...
- python3 stack/ queue和deque模块
'''栈stack 先进后出FILO (first in last out)'''lst = []lst.append("张一山")lst.append("杨紫" ...
- Hadoop 学生平均成绩
1.实例描述 通过一个计算学生平均成绩的例子来讲解开发MapReduce程序的流程.输入文件都是纯文本文件,输入文件中的每行内容均为一个学生的姓名和他相应的成绩,如果有多门学科,则每门学科为一个文件. ...
- Android单元测试之三:使用模拟框架模拟依赖
Android单元测试之三:使用模拟框架模拟依赖 基本描述 如果是一些工具类方法的测试,如计算两数之和的方法,本地 JVM 虚拟机就能提供足够的运行环境,但如果要测试的单元依赖了 Android 框架 ...
- [Swift]LeetCode959. 由斜杠划分区域 | Regions Cut By Slashes
In a N x N grid composed of 1 x 1 squares, each 1 x 1 square consists of a /, \, or blank space. Th ...
- [Swift]LeetCode1025. 除数博弈 | Divisor Game
Alice and Bob take turns playing a game, with Alice starting first. Initially, there is a number N o ...
- 隔壁老主精讲web页面性能优化。
首先说一下为什么要进行web页面性能优化,在同样的网络环境下,两个同样能满足你的需求的网站,一个“Biu”的一下就加载出来了,一个卡--卡--卡--卡--卡--才出来,你会选择哪个?研究表明:用户最满 ...
- [Abp 源码分析]一、Abp 框架启动流程分析
Abp 不一定仅用于 Asp.Net Core 项目,他也可以在 Console 与 WinFrom 项目当中进行使用,所以关于启动流程可以分为两种,一种是 Asp.Net Core 项目的启动流程, ...