任务表示应完成的某个单元的工作。这个单元的工作可以在单独的线程中运行,也可以以同步方式启动一个任务,这需要等待主调用线程。使用任务不仅可以获得一个抽象层,还可以对底层线程进行很多控制。

1.启动任务

要启动任务,可以使用TaskFactory类或Task类的构造函数和Start()方法。Task类的构造函数在创建任务上提供的灵活性较大。

1).任务方法

    static object taskMethodLock = new object();
static void TaskMethod(object title)
{
lock (taskMethodLock)
{
Console.WriteLine(title);
Console.WriteLine("Task id: {0}, thread: {1}",
Task.CurrentId == null ? "no task" : Task.CurrentId.ToString(),
Thread.CurrentThread.ManagedThreadId);
Console.WriteLine("is pooled thread: {0}", Thread.CurrentThread.IsThreadPoolThread);
Console.WriteLine("is background thread: {0}", Thread.CurrentThread.IsBackground);
Console.WriteLine();
}
}

2).使用线程池的任务

    static void TasksUsingThreadPool()
{
var tf = new TaskFactory();
Task t1 = tf.StartNew(TaskMethod, "using a task factory"); Task t2 = Task.Factory.StartNew(TaskMethod, "factory via a task"); var t3 = new Task(TaskMethod, "using a task constructor and Start");
t3.Start(); Task t4 = Task.Run(() => TaskMethod("using the Run method"));
}

执行结果:

3).同步任务

任务也可以同步运行,已相同的线程作为主调用线程。

注:主线程是一个调用前台线程,没有任务ID,也不是线程池中的线程。

    private static void RunSynchronousTask()
{
TaskMethod("just the main thread");
var t1 = new Task(TaskMethod, "run sync");
t1.RunSynchronously();
}

执行结果:

4).使用单独线程的任务

如果任务的代码应该长时间运行,就应该使用TaskCreationOptions.LogRunning告诉任务调度器创建一个新线程,而不是使用线程池中的线程。

    private static void LongRunningTask()
{
var t1 = new Task(TaskMethod, "long running", TaskCreationOptions.LongRunning);
t1.Start();
}

执行结果:

2.Future——任务结果

任务结束时,它可以把一些有用的状态信息写到共享对象中。这个对象必须是线程安全的。另一个选项是使用返回某个结果的任务。这种任务也叫Future,因为它返回一个结果。

    static Tuple<int, int> TaskWithResult(object division)
{
Tuple<int, int> div = (Tuple<int, int>)division;
int result = div.Item1 / div.Item2;
int reminder = div.Item1 % div.Item2;
Console.WriteLine("task creates a result..."); return Tuple.Create<int, int>(result, reminder);
}
    static void ResultsFromTasks()
{
var t1 = new Task<Tuple<int, int>>(TaskWithResult, Tuple.Create<int, int>(, ));
t1.Start();
Console.WriteLine(t1.Result);
t1.Wait();
Console.WriteLine("result from task: {0} {1}", t1.Result.Item1, t1.Result.Item2);
}

执行结果:

3.连续任务

通过任务,可以指定在任务完成后,应开始运行另一个特定任务。

注:无论前一个任务是如何结束的,前面的连续任务总是在前一个任务结束时启动。使用TaskContinuationOptions枚举中的值,可以指定,连续任务只有在起始任务成功(或失败)结束时启动。一些可能的值是OnlyOnFaulted、NotOnFaulted、OnlyOnCanceled和OnlyOnRanToCompletion。

    static void DoOnFirst()
{
Console.WriteLine("doing some task {0}", Task.CurrentId);
Thread.Sleep();
} static void DoOnSecond(Task t)
{
Console.WriteLine("task {0} finished", t.Id);
Console.WriteLine("this task id {0}", Task.CurrentId);
Console.WriteLine("do some cleanup");
Thread.Sleep();
} static void DoOnError(Task t)
{
Console.WriteLine("task {0} had an error!", t.Id);
Console.WriteLine("my id {0}", Task.CurrentId);
Console.WriteLine("do some cleanup");
}
    static void ContinuationTask()
{
Task t1 = new Task(DoOnFirst);
Task t2 = t1.ContinueWith(DoOnSecond);
Task t3 = t1.ContinueWith(DoOnSecond);
Task t4 = t2.ContinueWith(DoOnSecond);
Task t5 = t1.ContinueWith(DoOnError, TaskContinuationOptions.OnlyOnFaulted);
t1.Start(); Thread.Sleep();
}

执行结果:

4.任务层次结构

利用任务连续性,可以在一个任务结束后启动另一个任务。任务也可以构成一个层次结构。一个任务启动一个新任务时,就启动了一个父/子层次结构。

如果父任务在子任务之前结束,父任务的状态就显示为:WaitingForChildrenToComplete。所有的子任务也结束时,父任务的状态就变成RanToCompletion。

static void ParentAndChild()
{
var parent = new Task(ParentTask);
parent.Start();
Thread.Sleep();
Console.WriteLine(parent.Status);
Thread.Sleep();
Console.WriteLine(parent.Status); }
static void ParentTask()
{
Console.WriteLine("task id {0}", Task.CurrentId);
var child = new Task(ChildTask); // , TaskCreationOptions.DetachedFromParent);
child.Start();
Thread.Sleep();
Console.WriteLine("parent started child");
// Thread.Sleep(3000);
}
static void ChildTask()
{
// Console.WriteLine("task id {0}, parent: {1}", Task.Current.Id, Task.Current.Parent.Id);
Console.WriteLine("child");
Thread.Sleep();
Console.WriteLine("child finished");
}

执行结果:

Task类(任务)的更多相关文章

  1. Darwin Streaming server 的 Task 类

    Darwin Streaming Server 是一个开放源代码的streaming server,对于streaming server的编程和软件结构有着一定的参考价值,它是使用C++写的,其中的并 ...

  2. C#中假设正确使用线程Task类和Thread类

    C#中使用线程Task类和Thread类小结 刚接触C#3个月左右.原先一直使用C++开发.由于公司的须要,所地採用C#开发.主要是控制设备的实时性操作,此为背景. 对于C#中的Task和Thread ...

  3. 并行模式库PPL应用实战(一):使用task类创建并行任务

    自 VS2010 起,微软就在 CRT 中集成了并发运行时(Concurrency Runtime),并行模式库(PPL,Parallel Patterns Library)是其中的一个重要组成部分. ...

  4. ArcGIS API for JavaScript 4.2学习笔记[31] (补充学习)Task类

    Task这个东西很有用,是AJS中用于解决各种乱七八糟任务的一个类.它有很多子类,有用于空间分析的,有用于空间查询的,等等. 这篇作为补充学习的第一篇,也是进阶学习的第一篇,我就改个写法. 我将使用思 ...

  5. Class:Task 类

    ylbtech-.Net-Class:Task 类 1. Task 类返回顶部 1-1. #region 程序集 mscorlib, Version=4.0.0.0, Culture=neutral, ...

  6. c#Task类。实现异步的一种方式

    Task和Task<TResult>是c#提供的一种实现异步功能的2个类.Task<TResult>继承Task类,有返回参数. 1.基本用法 不嵌套利用静态方法创建和运行任务 ...

  7. 1、Task类构造函数

    Task类的构造函数接收一个无参无返回值的委托: 1: Task task = new Task(TaskMethod); 2: task.Start();例子:  task = new Task(( ...

  8. Task类学习教程—组合任务ContinueWith

    Task类学习教程-组合任务.ContinueWith 一.简介 通过任务,可以指定在任务完成之后,应开始运行之后另一个特定任务.ContinueWith是Task根据其自身状况,决定后续应该作何操作 ...

  9. 关于Task类

    private static void tt2() { Task task = null; ; i < ; i++) { task = Task.Factory.StartNew(callbac ...

随机推荐

  1. nyist 61 传纸条 nyist 712 探 寻 宝 藏(双线程dp问题)

    http://acm.nyist.net/JudgeOnline/problem.php?pid=61 http://acm.nyist.net/JudgeOnline/problem.php?pid ...

  2. show processlist 输出ID 和 information_schema.PROCESSLIST 的id,information_schema.innodb_trx的TRX_MYSQL_T

    Session 1: mysql> start transaction; Query OK, 0 rows affected (0.00 sec) mysql> update Client ...

  3. 【HDOJ】3068 最长回文

    马拉车算法O(n)可解. /* 3068 */ #include <iostream> #include <string> #include <map> #incl ...

  4. poj2104

    裸的主席树,没什么好说的 type node=record        l,r,s:longint;      end; ..] of node;     sa,rank,a,b,sum,head: ...

  5. java基于xml配置的通用excel单表数据导入组件(三、负责数据转换处理的类)

    package xxxxxxx.manage.importexcel; import java.util.Map; import java.util.logging.Logger; import xx ...

  6. 【转】提供android 5.0 AOSP源码下载

    http://blog.csdn.net/innost/article/details/41148335 android-5.0.tar.gz 115网盘礼包码:5lbcl16a1k7q http:/ ...

  7. android开发板

    element14-beaglebone-black http://www.embest-tech.cn/shop/star/element14-beaglebone-black-rev-c.html ...

  8. Tag file directory /struts-tags does not start with "/WEB-INF/tags"

    使用自定义标签,记得引用路径 <%@taglib prefix="s" uri="/struts-tags" %>

  9. Design T-Shirt

    Design T-Shirt Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)To ...

  10. DATEDIFF()(转)

    SQL DATEDIFF 函数 Leave a reply SQL DATEDIFF() 函数用来返回2个时间的差.这个函数在SQL Server和MySQL中都有,但语法上有不同. SQL CASE ...