0%

C#中关于Task、Task.ContinueWith()和Task.WaitAll()的用法

C#多线程编程

在C#的多线程编程中,一般可以使用Thread Class来进行多线程运行,但从.net4.0开始,引进了Task Class之后,官方更推荐用Task类来异步编程。
创建一个进程需要一定的开销和时间,特别是多个线程的时候,必须考虑创建和销毁线程需要的系统开销,这时就需要用到Thread pool线程池来管理线程,防止频繁的创建和销毁线程。但是,.net4.0之后,微软创建了一个优化的Task类,它默认会创建线程池来管理task,使用起来更加方便,系统开销更小。可参见stackoverflow上关于Task和Thread的回答,因此,学习和使用Task是很有必要的。

Task使用方式

详细方法可以参阅codeproject的文章,写的比较详细具体。简单点来说的话,Task类的使用可以分成3种。

  • Task.Factory.StartNew(Action action)

  • Task.Run(Action action)

  • Task task = new Task(Action action);
    task.Start();
    <!--0-->
    

输出结果为

1
2
3
4
5
Task ContinueWith test begins:
task step1
task step2
this is a main thread
task stpe3

从实际用法来看,执行完Task.Run()之后接着异步运行ContinueWith()的任务。

Task.WaitAll()的用法

进一步的,如何知道Task是否运行结束,可以使用Task.WaitAll()

Waits for all of the provided Task objects to complete execution

运行一个简单的控制台例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using System.Threading;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
List<Task> taskList = new List<Task>();
Console.WriteLine("Task WaitAll test begins:");
for (int i=0; i < 5; i++)
{
Task task = doTask(i);
taskList.Add(task);
}
Task.WaitAll(taskList.ToArray());
Console.WriteLine("this is a main thread");
Console.ReadLine();
}

public static Task doTask(int i)
{
return Task.Run(() => {
Console.WriteLine("task step1 of " + i.ToString());
}).ContinueWith((preTask) => {
Console.WriteLine("task step2 of " + i.ToString());
}).ContinueWith((preTask) => {
Console.WriteLine("task step3 of " + i.ToString());
});

}

}
}

创建了5个子线程,同时运行,运行结果是

Task.WaitAll

Task.WaitAll是等待所有的Task运行结束,但是会阻塞当前线程,如果是在WinForm编程的话,为了防止UI主线程被阻塞,应该创建一个子线程来等待。

------------ 本文已结束,感谢您的阅读,欢迎留言讨论 ------------