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

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. JavaScript日期时间操作

    <script> var d=new Date();//当前时间 alert(d); var d1=new Date(1992,5,19);//定义一个时间,月份要加1; alert(d1 ...

  2. android Spinner的使用

    首先是MainActivity package com.example.spinnertest; import java.util.ArrayList; import java.util.List; ...

  3. 【Android 开源】:最火的Android开源项目 第02期

    21. drag-sort-listview DragSortListView(DSLV)是Android ListView的一个扩展,支持拖拽排序和左右滑动删除功能.重写了TouchIntercep ...

  4. Android --- px与dip换算

    px = (density/160)dpdensity一般为3个常用固定值240/160/120分别对应WVGA/HVGA/QVGA不知道知己做的分辨率对应的density是多少可以点击AVD Man ...

  5. CSS中背景图片定位方法

    转自:http://www.ruanyifeng.com/blog/2008/05/css_background_image_positioning.html 作者: 阮一峰 日期: 2008年5月 ...

  6. C#中类的默认访问是私有的

    如果类前面没有访问修饰符的话,那里面的成员默认是私有private. 下面的代码是从MSDN上拷的,那个d它说明了私有:class Employee{private int i;double d; / ...

  7. ambari的重新安装

    ambari是什么呢? 这里我简单说一下ambari的目的,他的目的就是简化hadoop集群的安装和管理.对于安装简化到什么地步呢?只需要几个命令,在页面上配置几个参数,几百几千个节点的集群就能安装成 ...

  8. General: Know How to Use InetAddress

    Modern applications often need the ability to learn information about hosts out on the network. One ...

  9. C#实现SOAP调用WebService

    最近写了一个SOA服务,开始觉得别人拿到我的服务地址,然后直接添加引用就可以使用了,结果"大牛"告知不行. 让我写一个SOAP调用服务的样例,我有点愣了,因为没做过这方面的,于是搞 ...

  10. innerHTML和innerText

    document 对象中有innerHTML和innerText 两个属性, 这两个属性都是获取document对象的文本内容的,这两个属性间有哪些区别呢?通过几个例子来看一下. 示例1 <ht ...