C# 多任务之 Task
Task 是什么 ?
Task 是一个类, 它表示一个操作不返回一个值,通常以异步方式执行。
Task 对象是一个的中心思想 基于任务的异步模式 首次引入.NET Framework 4 中。
因为由执行工作 Task 对象通常以异步方式执行在线程池线程上而不是以同步方式在主应用程序线程,您可以使用 Status 属性,以及 IsCanceled, ,IsCompleted, ,和 IsFaulted 属性,以确定任务的状态。 大多数情况下,lambda 表达式用于指定的任务是执行的工作。
Task 怎么用 ?
Task 可以多种方式创建实例。 最常用的方法,它位于开头 .NET Framework 4.5, ,是调用静态 Run 方法。 Run 方法提供了简单的方法来启动任务使用默认值,并且无需额外的参数。 下面的示例使用 Run(Action) 方法来启动循环,然后显示循环迭代数的任务︰
using System;
using System.Threading.Tasks; public class Example
{
public static void Main()
{
Task t = Task.Run( () => {
// Just loop.
int ctr = 0;
for (ctr = 0; ctr <= 1000000; ctr++)
{}
Console.WriteLine("Finished {0} loop iterations",
ctr);
} );
t.Wait();
}
}
using System;
using System.Threading.Tasks; public class Example
{
public static void Main()
{
Task t = Task.Factory.StartNew( () => {
// Just loop.
int ctr = 0;
for (ctr = 0; ctr <= 1000000; ctr++)
{}
Console.WriteLine("Finished {0} loop iterations",
ctr);
} );
t.Wait();
}
}
因为任务通常运行以异步方式在线程池线程上,创建并启动任务的线程将继续执行,一旦该任务已实例化。 在某些情况下,当调用线程的主应用程序线程,该应用程序可能会终止之前任何任务实际开始执行。 其他情况下,应用程序的逻辑可能需要调用线程继续执行,仅当一个或多个任务执行完毕。 您可以同步调用线程的执行,以及异步任务它启动通过调用 Wait 方法来等待要完成的一个或多个任务。
若要等待完成一项任务,可以调用其 Task.Wait 方法。 调用 Wait 方法将一直阻塞调用线程直到单一类实例都已完成执行。
下面的示例调用无参数 Wait() 方法,以无条件地等待,直到任务完成。 该任务通过调用来模拟工作 Thread.Sleep 方法进入睡眠状态两秒钟。
using System;
using System.Threading;
using System.Threading.Tasks; class Program
{
static Random rand = new Random(); static void Main()
{
// Wait on a single task with no timeout specified.
Task taskA = Task.Run( () => Thread.Sleep(2000));
Console.WriteLine("taskA Status: {0}", taskA.Status);
try {
taskA.Wait();
Console.WriteLine("taskA Status: {0}", taskA.Status);
}
catch (AggregateException) {
Console.WriteLine("Exception in taskA.");
}
}
}
您可以有条件地等待任务完成。 Wait(Int32) 和 Wait(TimeSpan) 方法阻止调用线程,直到任务完成或超时间隔结束,具体取决于第一个。 由于下面的示例将启动一个任务,它在睡眠两秒钟,但定义的一秒的超时值,调用线程受到阻止,直到超时到期和之前的任务已完成执行。
using System;
using System.Threading;
using System.Threading.Tasks; public class Example
{
public static void Main()
{
// Wait on a single task with a timeout specified.
Task taskA = Task.Run( () => Thread.Sleep(2000));
try {
taskA.Wait(1000); // Wait for 1 second.
bool completed = taskA.IsCompleted;
Console.WriteLine("Task A completed: {0}, Status: {1}",
completed, taskA.Status);
if (! completed)
Console.WriteLine("Timed out before task A completed.");
}
catch (AggregateException) {
Console.WriteLine("Exception in taskA.");
}
}
}
你也可以通过调用提供一个取消标记 Wait(CancellationToken) 和 Wait(Int32, CancellationToken) 方法。 如果该令牌的 IsCancellationRequested 属性是 true, ,取消等待; 如果它变为 true 时 Wait 方法终止。
在某些情况下,您可能想要等待的执行的任务的一系列的第一个完成,但不是任务它的关注。 出于此目的,您可以调用的重载之一 Task.WaitAll 方法。 下面的示例创建三个任务,其中每个休眠的随机数字生成器确定时间间隔。 WaitAny(Task[]) 方法等待第一个任务完成。 此示例随后显示所有三个任务的状态的信息。
using System;
using System.Threading;
using System.Threading.Tasks; public class Example
{
public static void Main()
{
var tasks = new Task[3];
var rnd = new Random();
for (int ctr = 0; ctr <= 2; ctr++)
tasks[ctr] = Task.Run( () => Thread.Sleep(rnd.Next(500, 3000))); try {s
int index = Task.WaitAny(tasks);
Console.WriteLine("Task #{0} completed first.\n", tasks[index].Id);
Console.WriteLine("Status of all tasks:");
foreach (var t in tasks)
Console.WriteLine(" Task #{0}: {1}", t.Id, t.Status);
}
catch (AggregateException) {
Console.WriteLine("An exception occurred.");
}
}
}
您也可以等待所有任务的调用以完成一系列 WaitAll 方法。 下面的示例创建十个任务,等待所有十若要完成,然后显示其状态。
using System;
using System.Threading;
using System.Threading.Tasks; public class Example
{
public static void Main()
{
// Wait for all tasks to complete.
Task[] tasks = new Task[10];
for (int i = 0; i < 10; i++)
{
tasks[i] = Task.Run(() => Thread.Sleep(2000));
}
try {
Task.WaitAll(tasks);
}
catch (AggregateException ae) {
Console.WriteLine("One or more exceptions occurred: ");
foreach (var ex in ae.Flatten().InnerExceptions)
Console.WriteLine(" {0}", ex.Message);
} Console.WriteLine("Status of completed tasks:");
foreach (var t in tasks)
Console.WriteLine(" Task #{0}: {1}", t.Id, t.Status);
}
}
请注意,等待一个或多个任务完成时,则在正在运行的任务引发的任何异常传播调用的线程上 Wait 方法,如以下示例所示。 它将启动其中三个正常完成的 12 任务和三个哪些引发的异常。 剩余的六项任务,三个早于开始日期,将被取消,而三个将被取消时执行它们。 引发异常 WaitAll 方法调用,并且是处理 try/catch 块。
using System;
using System.Threading;
using System.Threading.Tasks; public class Example
{
public static void Main()
{
// Create a cancellation token and cancel it.
var source1 = new CancellationTokenSource();
var token1 = source1.Token;
source1.Cancel();
// Create a cancellation token for later cancellation.
var source2 = new CancellationTokenSource();
var token2 = source2.Token; // Create a series of tasks that will complete, be cancelled,
// timeout, or throw an exception.
Task[] tasks = new Task[12];
for (int i = 0; i < 12; i++)
{
switch (i % 4)
{
// Task should run to completion.
case 0:
tasks[i] = Task.Run(() => Thread.Sleep(2000));
break;
// Task should be set to canceled state.
case 1:
tasks[i] = Task.Run( () => Thread.Sleep(2000),
token1);
break;
case 2:
// Task should throw an exception.
tasks[i] = Task.Run( () => { throw new NotSupportedException(); } );
break;
case 3:
// Task should examine cancellation token.
tasks[i] = Task.Run( () => { Thread.Sleep(2000);
if (token2.IsCancellationRequested)
token2.ThrowIfCancellationRequested();
Thread.Sleep(500); }, token2);
break;
}
}
Thread.Sleep(250);
source2.Cancel(); try {
Task.WaitAll(tasks);
}
catch (AggregateException ae) {
Console.WriteLine("One or more exceptions occurred:");
foreach (var ex in ae.InnerExceptions)
Console.WriteLine(" {0}: {1}", ex.GetType().Name, ex.Message);
} Console.WriteLine("\nStatus of tasks:");
foreach (var t in tasks) {
Console.WriteLine(" Task #{0}: {1}", t.Id, t.Status);
if (t.Exception != null) {
foreach (var ex in t.Exception.InnerExceptions)
Console.WriteLine(" {0}: {1}", ex.GetType().Name,
ex.Message);
}
}
}
}
四: 并行迭代 Task.Parallel
API 会判定同时执行多少个线程效率最高。效率由一个爬山算法来决定。
一个parallel并行的例子
C# 多任务之 Task的更多相关文章
- C# Task 多任务 限制Task并发数量
LimitedTaskScheduler: using System; using System.Collections.Concurrent; using System.Collections.Ge ...
- C#多线程の遇见长耗时操作以及多任务(简明记要)
4.0用 Task.Factory.StartNew(()=>{});4.0以下用 ThreadPool.QueueUserWorkItem(()=>{})4.0以上用 ...
- JSRE中的多任务与多线程
前言 这几天在爱智官网看了下JSRE其他的Api,看了一个比较有意思的模块 - 多任务模块task,大致看了下他们的接口说明和案例,感觉和多线程差不多,然后就准备去看下实现方式,找了很久没有找到源 ...
- Java Gradle入门指南之简介、安装与任务管理
这是一篇Java Gradle入门级的随笔,主要介绍Gradle的安装与基本语法,这些内容是理解和创建build.gradle的基础,关于Gradle各种插件的使用将会在其他随笔中介绍. ...
- Gradle项目构建(1)——Gradle的由来
一.项目自动构建介绍 作为Java的开发者对eclipse都非常熟悉,其实eclipse就是居于ant来构建项目的,我们先来看看为什么需要自动化构建项目. 1.为什么我们要自动化构建项目 可以假设我们 ...
- Gradle系列之构建脚本基础
原文发于微信公众号 jzman-blog,欢迎关注交流. 前面两篇文章分别介绍了 Gradle 基础知识以及 Groovy 相关基础知识,这也是学习 Gradle 所必需了解的,文章链接如下:: Gr ...
- 重新想象 Windows 8 Store Apps (43) - 多线程之任务: Task 基础, 多任务并行执行, 并行运算(Parallel)
[源码下载] 重新想象 Windows 8 Store Apps (43) - 多线程之任务: Task 基础, 多任务并行执行, 并行运算(Parallel) 作者:webabcd 介绍重新想象 W ...
- C# 使用Task实现任务超时,多任务一起执行
简介:充分使用Task的异步功能代码实现:1.实现了任务超时 退出任务 2.多个任务一起执行 /// <summary> ///做事 需要 ms秒 才能完成 / ...
- .NET使用Task动态创建多任务多线程并行程序计算Redis集群keys计算
Task是一个很好用的多任务处理类,并且通过Task可以对任务进行很好的控制. 下面将通过代码实现Redis集群在使用IServer.keys时通过多任务对多个服务器示例进行并行计算,并对返回key做 ...
随机推荐
- Spider Studio 数据挖掘集成开发环境
(最新版本: 2.7.12.1) 传统的多线程蜘蛛程序虽然采集速度快, 但是明明不需要所有内容, 却胡子眉毛一把抓, 将整个网页都下载下来当作一个文本进行处理. 由于网页内容参差不齐, 所以抓取质量常 ...
- iOS 应用数据存储的常用方式
iOS 开发中,经常会有将数据存储到本地的需求.比如一些数据的缓存,或者记录下用户的账号密码,记录下下次是否自动登录等,这些都需要将数据记录到本地.iOS中,数据存储到本地的常见方式有三种: 一: 使 ...
- Ms SQL Server 约束和规则
一.SQL约束 约束定义关于列中允许值的规则,是强制完整性的标准机制. 使用约束优先于使用触发器.规则和默认值.查询优化器也使用约束定义生成高性能的查询执行计划. 1:类型 约束的类型一共分三种 域约 ...
- javasctipt显示几分钟前、几天前等
jsp页面: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> ...
- Hdu 5444 Elven Postman dfs
Elven Postman Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid= ...
- [Bootstrap] 4. Typogrphy
What is Typography When we talk about typography, it's a big subject! Which of the following fall un ...
- Lazy Load 图片延迟加载(转)
jQuery Lazy Load 图片延迟加载来源 基于 jQuery 的图片延迟加载插件,在用户滚动页面到图片之后才进行加载. 对于有较多的图片的网页,使用图片延迟加载,能有效的提高页面加载速度. ...
- spring Transaction Management --官方
原文链接:http://docs.spring.io/spring/docs/current/spring-framework-reference/html/transaction.html 12. ...
- C++ (P160—)多继承 二义性 虚基类 “向上转型”
1 多继承中,必须给每个基类指定一种派生类型,如果缺省,相应的基类则取私有派生类型,而不是和前一个基类取相同的派生类型 2 一个类的保护成员只能被本类的成员函数或者它的派生类成员函数访问 3 由于c+ ...
- C#基础篇03
1:不管是实参还是形参,都在内存中开辟空间. 2:写一个方法,它的功能一定要单一,方法中最忌讳的就是出现提示用户输入的字眼. 3:out参数 如果在一个方法中,返回多个类型相同的值时,可以考虑返回一个 ...