使用线程池使得创建线程已经很简单了,但是使用线程池不支持线程的取消,完成和失败通知等交互操作,为了解决这些问题,.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的更多相关文章

  1. 【多线程】 Task ,async ,await

    [多线程]Task ,async ,await 一. WinForm 里经常会用到多线程, 多线程的好出就不多说了,来说说多线程比较麻烦的地方 1. UI 线程与其他线程的同步,主要是 Form 和 ...

  2. 【多线程】 Task

    [多线程] Task 一. 常用方法: 1. ContinueWith : 当前 Task 完成后, 执行传入的 Task 2. Delay : 创建一个等待的 Task,只有在调用 Wait 方法时 ...

  3. .Net 多线程 (1) Task

    多线程是一种有效提高程序工作效率的方法.当然为了效率需要使用更多的cpu,内存等资源. 并发是两个队列交替使用一台咖啡机,并行是两个队列同时使用两台咖啡机,如果串行,一个队列使用一台咖啡机,那么哪怕前 ...

  4. 【多线程】Task

    介绍 Task是.NET推出数据任务处理的工作类.位于System.Threading.Tasks命名空间下,通过命名空间也可以看出是个多线程类. 创建Task: Task有很多构造函数,无参有参都有 ...

  5. C#多线程编程のTask(任务全面解析)

    Task是.NET4.0加入的,跟线程池ThreadPool的功能类似,用Task开启新任务时,会从线程池中调用线程,而Thread每次实例化都会创建一个新的线程. 我们可以说Task是一种基于任务的 ...

  6. C# 应用 - 多线程 3) Task.Factory

    1. 与 Task.Run() 的区别: 先看一下源码: public class Task : IThreadPoolWorkItem, IAsyncResult, IDisposable { pu ...

  7. C# 应用 - 多线程 4) Task cancel

    1. 操作取消 1.1 步骤 实例化 CancellationTokenSource 对象,该对象管理取消通知并将其发送给单个取消标记 将 CancellationTokenSource.Token ...

  8. Task/Parallel实现异步多线程

    代码: #region Task 异步多线程,Task是基于ThreadPool实现的 { //TestClass testClass = new TestClass(); //Action<o ...

  9. .NET多线程(Thread,ThreadPool,Task,Async与Await)

    .NET多线程是什么? 进程与线程 进程是一种正在执行的程序. 线程是程序中的一个执行流. 多线程是指一个程序中可以同时运行多个不同的线程来执行不同的任务. .NET中的线程 Thread是创建和控制 ...

随机推荐

  1. npm修改淘宝原

    //修改之前查看一下npm config get registry https://registry.npmjs.org/ //设置源npm config set registry https://r ...

  2. React Native搭建开发环境 之 --走过的坑

    React Native是使用JavaScript和React编写原生移动应用 我的开发平台是基于windows系统,所以只支持android,要是想开发ios系统,那就只能考虑使用沙盒环境 接下来就 ...

  3. 别以为真懂Openstack: 虚拟机创建的50个步骤和100个知识点(4)

    六.Libvirt 对于Libvirt,在启动虚拟机之前,首先需要define虚拟机,是一个XML格式的文件 列出所有的Instance # virsh list Id    Name         ...

  4. 基于 TensorFlow 在手机端实现文档检测

    作者:冯牮 前言 本文不是神经网络或机器学习的入门教学,而是通过一个真实的产品案例,展示了在手机客户端上运行一个神经网络的关键技术点 在卷积神经网络适用的领域里,已经出现了一些很经典的图像分类网络,比 ...

  5. 字符串----HDU-1358

    题目大意:求字符串的前缀是否为周期串,若是,打印出循环节的长度以及循环次数. 这道题考察的是KMP算法中next数组的应用,必须理解透next[]数组代表的含义才t能通过它解决这道题.思路是先构造出 ...

  6. [Swift]LeetCode267.回文全排列 II $ Palindrome Permutation II

    Given a string s, return all the palindromic permutations (without duplicates) of it. Return an empt ...

  7. [Swift]LeetCode446. 等差数列划分 II - 子序列 | Arithmetic Slices II - Subsequence

    A sequence of numbers is called arithmetic if it consists of at least three elements and if the diff ...

  8. scala查询dataFrame结构

    println(dataFrame.printSchema)

  9. Python内置函数(49)——pow

    英文文档: pow(x, y[, z]) Return x to the power y; if z is present, return x to the power y, modulo z (co ...

  10. 项目总结四:神经风格迁移项目(Art generation with Neural Style Transfer)

    1.项目介绍 神经风格转换 (NST) 是深部学习中最有趣的技术之一.它合并两个图像, 即 内容图像 C(content image) 和 样式图像S(style image), 以生成图像 G(ge ...