首页 | 新闻 | 交流 | 问吧 | 文档 | 手册 | 下载 | 博客

C#4.0入门 第三章 Task类与PLINQ—第一页 Task类(转)

作者:  时间: 2011-06-11

Task类的基本使用方法
Task类为把线程类进行改良,使之更简便,使用起来更加容易的类。因此,虽然功能相似,但属于两个概念,使用方法也不相同。

要想利用Task类,开始任务,只要调用Task.Factory.StartNew方法就可以了。



task1.cs



 using System;
using System.Threading.Tasks;
class Program
{
static void Main(string[] args)
{
// 子任务
var task = Task.Factory.StartNew(() =>
{
for (int i = 0; i < 100; i++) Console.Write('B');
});
// 主任务
for (int i = 0; i < 100; i++) Console.Write('A');
task.Wait();
}
}


运行结果(结果因环境与时序而异)




 AAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB


主任务输出A,子任务输出B,因为两个任务并行执行,所以两个输出同时执行,输出结果的顺序不确定。




最后的Wait方法为,等待Task任务结束的功能。这样,可以确保子任务结束后再退出程序。

准备工作结束后做这个事情



预先指定当某个条件满足后应该要执行的代码的情况是经常会遇见的。




更为经常会遇见的情况是“当某个事情一旦做完后,我想接下来做这个事情”。如果利用Task类的话,这种想法很容易实现。


task2.cs



 
class Program
{
private static void notify(Task t)
{
Console.WriteLine();
Console.WriteLine("sub task {0} done", t.Id);
}
static void Main(string[] args)
{
var task = Task.Factory.StartNew(() =>
{
for (int i = 0; i < 100; i++) Console.Write('B');
});
task.ContinueWith(notify);
for (int i = 0; i < 100; i++) Console.Write('A');
task.Wait();
}
}


运行结果




 BBBBBBBBBBBBBBBBBBBBBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
sub task 1 done



如例中所示,只要利用ContinueWith方法就可以了。当然接下来所要执行的代码也可以用lambda表达式进行书写。这样,可以在指定任务结束后,执行ContinueWith方法。同时,可以针对同一个Task对象使用多次ContinueWith方法,当然是按指定时的顺序执行的。


另外,如果把notify方法用lambda表达式来进行改写,ContinueWith方法的调用如下例所示。


用lambda表达式改写notify方法



 
task.ContinueWith((t) =>
{
Console.WriteLine();
Console.WriteLine("sub task {0} done", t.Id);
});


这里lambda表达式的参数t与变量task所携带的内容是相同的,换句话说,值是相同的。象这样,调用方法M时象x.M(x)这样前后同样使用“x”的形式,叫做“显式的this指针”。“显式的this指针”在程序中的使用频率是非常高的。虽然同一行中同样的内容用两个名字来定义(本例中的task和t)的写法是不漂亮的,但是如果使用lambda表达式,就可以在lambda表达式内部引用变量task了。