Task 是什么 ?

Task 是一个类, 它表示一个操作不返回一个值,通常以异步方式执行。

Task 对象是一个的中心思想 基于任务的异步模式 首次引入.NET Framework 4 中。

System.Object
  System.Threading.Tasks.Task
    System.Threading.Tasks.Task<TResult>

因为由执行工作 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的更多相关文章

  1. C# Task 多任务 限制Task并发数量

    LimitedTaskScheduler: using System; using System.Collections.Concurrent; using System.Collections.Ge ...

  2. C#多线程の遇见长耗时操作以及多任务(简明记要)

    4.0用         Task.Factory.StartNew(()=>{});4.0以下用  ThreadPool.QueueUserWorkItem(()=>{})4.0以上用 ...

  3. JSRE中的多任务与多线程

    前言 ​ 这几天在爱智官网看了下JSRE其他的Api,看了一个比较有意思的模块 - 多任务模块task,大致看了下他们的接口说明和案例,感觉和多线程差不多,然后就准备去看下实现方式,找了很久没有找到源 ...

  4. Java Gradle入门指南之简介、安装与任务管理

        这是一篇Java Gradle入门级的随笔,主要介绍Gradle的安装与基本语法,这些内容是理解和创建build.gradle的基础,关于Gradle各种插件的使用将会在其他随笔中介绍.    ...

  5. Gradle项目构建(1)——Gradle的由来

    一.项目自动构建介绍 作为Java的开发者对eclipse都非常熟悉,其实eclipse就是居于ant来构建项目的,我们先来看看为什么需要自动化构建项目. 1.为什么我们要自动化构建项目 可以假设我们 ...

  6. Gradle系列之构建脚本基础

    原文发于微信公众号 jzman-blog,欢迎关注交流. 前面两篇文章分别介绍了 Gradle 基础知识以及 Groovy 相关基础知识,这也是学习 Gradle 所必需了解的,文章链接如下:: Gr ...

  7. 重新想象 Windows 8 Store Apps (43) - 多线程之任务: Task 基础, 多任务并行执行, 并行运算(Parallel)

    [源码下载] 重新想象 Windows 8 Store Apps (43) - 多线程之任务: Task 基础, 多任务并行执行, 并行运算(Parallel) 作者:webabcd 介绍重新想象 W ...

  8. C# 使用Task实现任务超时,多任务一起执行

    简介:充分使用Task的异步功能代码实现:1.实现了任务超时 退出任务 2.多个任务一起执行 /// <summary>        ///做事 需要 ms秒 才能完成        / ...

  9. .NET使用Task动态创建多任务多线程并行程序计算Redis集群keys计算

    Task是一个很好用的多任务处理类,并且通过Task可以对任务进行很好的控制. 下面将通过代码实现Redis集群在使用IServer.keys时通过多任务对多个服务器示例进行并行计算,并对返回key做 ...

随机推荐

  1. 上传GIF图片方法!

    有朋友问,如何上传GIF图片,在此做一下说明.方法是:在第二栏“上传图片”栏——选择“无水印”——选择文件(找到文件)——点击上传——点击插入——我选的图片 ——上传成功了!

  2. 命令删除visualstudio.com云端项目(TFS)

    1.运行命令行 2.tfsdeleteproject /collection:https://域名.visualstudio.com/DefaultCollection “项目名称”

  3. 剑指OFFER之最小的K个数(九度OJ1371)

    题目描述: 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 输入: 每个测试案例包括2行: 第一行为2个整数n,k(1< ...

  4. Android Error

    [2016-03-27 13:00:51 - XWeChat] Dx warning: Ignoring InnerClasses attribute for an anonymous inner c ...

  5. 关于python文件操作 (转载)

    总是记不住API.昨晚写的时候用到了这些,但是没记住,于是就索性整理一下吧: python中对文件.文件夹(文件操作函数)的操作需要涉及到os模块和shutil模块. 得到当前工作目录,即当前Pyth ...

  6. 【转】二叉树 VS hashtable

    hash_table和二叉搜索树都经常被用来构建符号表(或者字典)以及相关的结构,并且他们都表现出了很高的效率.最近也在不同的程序中使用了这两种数据结构,实现完毕后思考一下,对两者做了一个简单的比较: ...

  7. Windows Phone开发工具初体验【转载】

    Windows Phone开发工具在MIX 2010上火热登场了.Windows Mobile开发者们压抑许久的热情终于爆发出来,对于Windows Phone的华丽转身,开发者们褒贬不一,有人对Si ...

  8. joa-framework 工作流高速开发框架(jeecg官方工作流版本号) 公布

    -------------------------------------- version:  joa-framework1.0.0.beta 版本号: JOA 工作流高速开发框架   Date:  ...

  9. There is no Action mapped for action name XXX. - [unknown location]

    今天被这个问题费了不少时间,原因是缺少了 struts2-json-plugin-2.3.1.2.jar 包 当然,有时候也可能是缺少其他包, 把这个包添加到lib文件夹后还要刷新,clean一下,因 ...

  10. STL——迭代器的概念

    迭代器是一种抽象的设计概念,现实程序语言中并没有直接对应于这个概念的实物. 1 迭代器设计思维——STL关键所在 不论是泛型思维或STL的实际运用,迭代器都扮演这重要的角色.STL的中心思想在于:将数 ...