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

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. 码云分布式之 Brzo 服务器

    摘要: 码云是国内最大的代码托管平台,为了支持更大的用户规模,开发团队也在对一些组件进行大规模的重构. 前言 码云是国内最大的代码托管平台.码云基于 Gitlab 5.5 开发,经过几年的开发已经和官 ...

  2. 【HDOJ】3315 My Brute

    几乎与2853相同,MCMF. /* 2853 */ #include <iostream> #include <string> #include <map> #i ...

  3. 【CF】310 Div.1 C. Case of Chocolate

    线段树的简单题目,做一个离散化,O(lgn)可以找到id.RE了一晚上,额,后来找到了原因. /* 555C */ #include <iostream> #include <str ...

  4. SYS_CONTEXT 详细用法

    SELECT SYS_CONTEXT ('USERENV', 'TERMINAL') terminal,        SYS_CONTEXT ('USERENV', 'LANGUAGE') lang ...

  5. PHP 'ext/soap/php_xml.c'不完整修复多个任意文件泄露漏洞

    漏洞版本: PHP 5.4.1 PHP 5.3.13 PHP 5.3.12 PHP 5.3.11 PHP 5.3.10 PHP 5.3.1 PHP 5.3 漏洞描述: BUGTRAQ ID: 6237 ...

  6. Redis主从实现原理分析 [转]

    原文地址:http://blog.sina.com.cn/s/blog_7530db6f0100vegl.html 一, 实现原理图 (1)Slave服务器连接到Master服务器. (2)Slave ...

  7. Linux内核学习笔记1——系统调用原理【转】

    1什么是系统调用 系统调用,顾名思义,说的是操作系统提供给用户程序调用的一组“特殊”接口.用户程序可以通过这组“特殊”接口来获得操作系统内核提供的服务,比如用户可以通过文件系统相关的调用请求系统打开文 ...

  8. HDOJ/HDU 1251 统计难题(字典树啥的~Map水过)

    Problem Description Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己 ...

  9. 关于MySQL的分区(partion)

    1 CREATE TABLE part_tab ( c1 int default NULL, c2 ) default NULL, c3 date default NULL ) engine=myis ...

  10. Joomla的在线视频播放插件:AllVideos

    一个很好的插件,只需要在文章中插入一条简单的语句就可以实现视频播放,视频可以位于网站服务器上或其他视频网站的. 例如:{f4v}ShaHua-H264{/f4v}   我在使用中只有一个地方觉得需要更 ...