多线程(4)Task

 

  使用线程池使得创建线程已经很简单了,但是使用线程池不支持线程的取消,完成和失败通知等交互操作,为了解决这些问题,.net 4.0带来了TPL(Task Parallel Library)任务并行库,下面就来总结下Task的使用。

创建和运行任务

在.net 4.0下使用task创建一个线程非常简单,有两种方式,如下代码:

 View Code

 

输出结果:

需要注意的是:task也是基于线程池的,所以这两个任务的执行顺序是不固定的。 

取消任务

 创建一个新的任务之后,我们随时都可以取消它,取消方法如下代码:

 

 

 View Code

 输出结果:

创建任务集合并输出结果 

如下代码:

复制代码
 1 namespace ConsoleApplication21
 2 {
 3     class Program
 4     {
 5         static void Main(string[] args)
 6         {
 7             //创建任务集合并输出结果
 8             var tasks = new List<Task<string>>();
 9 
10             var task1 = Task.Factory.StartNew<string>(() => 
11             {
12                 Console.WriteLine("task1 running on thread id:"+ Thread.CurrentThread.ManagedThreadId);
13                 return "task1";
14             });
15             tasks.Add(task1);
16 
17             var task2 = Task.Factory.StartNew<string>(() =>
18             {
19                 Console.WriteLine("task2 running on thread id:" + Thread.CurrentThread.ManagedThreadId);
20                 return "task2";
21             });
22             tasks.Add(task2);
23 
24             var task3 = Task.Factory.StartNew<string>(() => 
25             {
26                 Console.WriteLine("task3 running on thread id:" + Thread.CurrentThread.ManagedThreadId);
27                 return "task3";
28             });
29             tasks.Add(task3);
30 
31             //输出结果
32             foreach (var item in tasks)
33             {
34                 Console.WriteLine(item.Result);//调用Task的Result方法相当于调用了Task.WaitAll(tasks.ToArray());
35             }
36 
37             Console.ReadKey(); 
38         }
39     }
40 }
复制代码

 

输出结果:

这里要注意2点:

1,每个任务会开启一个新的线程,并且运行顺序不固定。

2,Task.Result相当于调用了Wait方法,等待异步任务完成。

多任务的串行化

 如下代码:

复制代码
 1 namespace ConsoleApplication22
 2 {
 3     class Program
 4     {
 5         static void Main(string[] args)
 6         {
 7             //多任务的串行化
 8             var task1 = Task.Factory.StartNew(() => 
 9             {
10                 Console.WriteLine("start task1...");
11                 Console.WriteLine("current thread id:"+ Thread.CurrentThread.ManagedThreadId);
12             });
13 
14             var task2 = task1.ContinueWith((item) => 
15             {
16                 Console.WriteLine("start task2...");
17                 Console.WriteLine("current thread id:" + Thread.CurrentThread.ManagedThreadId);
18             });
19 
20             var task3 = task2.ContinueWith((item)=>
21             {
22                 Console.WriteLine("start task3...");
23                 Console.WriteLine("current thread id:" + Thread.CurrentThread.ManagedThreadId);
24             });
25 
26             Console.ReadKey();
27         }
28     }
29 }
复制代码

 输出结果:

注意,多任务串行化后,就相当于顺序执行了,而且有可能使用的是同一个线程,从上图的thread id就可以看出来。

多任务等待执行完成

如下代码:

复制代码
 1 namespace ConsoleApplication23
 2 {
 3     class Program
 4     {
 5         static void Main(string[] args)
 6         {
 7             //多任务等待执行完成
 8             var tasks = new List<Task<string>>();
 9 
10             var task1 = Task.Factory.StartNew<string>(() => 
11             {
12                 Console.WriteLine("task1");
13                 return "task1";
14             });
15             tasks.Add(task1);
16 
17             var task2 = Task.Factory.StartNew<string>(() => 
18             {
19                 Console.WriteLine("task2");
20                 return "task2";
21             });
22             tasks.Add(task2);
23 
24             var task3 = Task.Factory.StartNew<string>(() => 
25             {
26                 Console.WriteLine("task3");
27                 return "task3";
28             });
29             tasks.Add(task3);
30 
31             //等待所有任务完成
32             Task.WaitAll(tasks.ToArray());
33 
34             //等价于下面的调用
35             //foreach (var item in tasks)
36             //{
37             //    item.Result
38             //}
39 
40             Console.ReadKey();
41         }
42     }
43 }
复制代码

 

输出结果:

需要注意的是,如果是有返回值的task,可以使用Task.Result获取返回值的同时,也在等待Task执行完成,相当于调用了Task.Wait方法。

创建子任务

如下代码:

复制代码
 1 namespace ConsoleApplication24
 2 {
 3     class Program
 4     {
 5         static void Main(string[] args)
 6         {
 7             //创建子任务
 8             var parentTask = Task.Factory.StartNew(() => 
 9             {
10                 Console.WriteLine("parent task!");
11                 var childTask = Task.Factory.StartNew(() => 
12                 {
13                     Console.WriteLine("child task!");
14                 }, TaskCreationOptions.AttachedToParent);
15             });
16 
17             Console.ReadKey();
18         }
19     }
20 }
复制代码

 

输出结果:

 

 
分类: C#基础

posted on 2025-03-19 18:59  漫思  阅读(9)  评论(0)    收藏  举报

导航