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做 ...
随机推荐
- Javascript注意事项二【避免误用parseInt】
parseInt("123abc"); //123parseInt("1.73"); //1parseInt(".123"); //NaN ...
- 学习和理解C#中的事件
注:本文系学习笔记. 上一篇文章记录了我对C#中委托的理解.委托实际上是一种类型.可以将一个或多个方法绑定到委托上面,调用委托时,一次执行委托上面绑定的方法.本文要讲述的事件实际上和委托有很深的“感情 ...
- mac不可或缺的套件管理器Homebrew
Homebrew 1.简介 可以帮助我们快速安装软件, 如 brew install svn 快速卸载软件 , 如 brew uninstall svn 2.下载 打开终端, /usr/bin/ru ...
- Android设计模式—策略模式
1.策略模式概念 定义一系列算法,把他们独立封装起来,并且这些算法之间可以相互替换.策略模式主要是管理一堆有共性的算法,客户端可以根据需要,很快切换这些算法,并且保持可扩展性. 策略模式的本质:分离算 ...
- ZZTHX-Androidannotations框架联想
我们首先来看一段代码: 在android开发中findViewById是最常用的一个方法,用来实例化页面上的控件,基本上每个控件都需要调用一次的,加入我们页面上有100个需要使用,那么findView ...
- HadoopDB:混合分布式系统
HadoopDB 是一个 Mapreduce 和传统关系型数据库的结合方案,以充分利用 RDBMS 的性能和 Hadoop 的容错.分布特性.2009 年被 Yale 大学教授 Abadi 提出,继而 ...
- maven配置编译路径
在build标签下添加 <build> <sourceDirectory>src/main/java</sourceDirectory> <resources ...
- [原创]VS2013 EF6连接MySql需要几步?
精简的美丽...... 1.安装mysql server下载地址 http://cdn.mysql.com/Downloads/MySQL-5.6/mysql-5.6.21-winx64.zip注意: ...
- careercup-中等难度 17.6
17.6 给定一个整数数组,编写一个函数,找出索引m和n,只要将m和n之间的元素排好序,整个数组就是有序的.注意:n越小越好,也就是说,找出符合条件的最短序列. 解法: 开始解题之前,让我们先确认一下 ...
- insert erase和replace的例子
9.43 编写一个函数,接受三个string参数s.oldVal和newVal.使用迭代器及insert和erase函数将s中所有oldval替换为newVal.测试程序,用它替换通用的简写形式,如, ...