C# TPL学习
程序Ⅰ:通过Task类创建新线程
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace Test000 { class Program { /// <summary> /// Task类封装 /// </summary> class MyTask { /// <summary> /// 第一个Task类,每秒计数,计数5次 /// </summary> public static void T1() { Console.WriteLine( "Task #{0}: Begin!" , Task.CurrentId); for ( int i = 0; i < 5; i++) { Thread.Sleep(1000); Console.WriteLine( "Task #{0}: {1}" , Task.CurrentId, i); } Console.WriteLine( "Task #{0}: Terminated!" , Task.CurrentId); } /// <summary> /// 第二个Task类,每秒计数,计数5次 /// </summary> public static void T2() { Console.WriteLine( "Task #{0}: Begin!" , Task.CurrentId); Thread.Sleep(500); for ( int i = 0; i < 5; i++) { Thread.Sleep(1000); Console.WriteLine( "Task #{0}: {1}" , Task.CurrentId, i); } Console.WriteLine( "Task #{0}: Terminated!" , Task.CurrentId); } } static void Main( string [] args) { //建立两个Task Task tsk1 = new Task(MyTask.T1); Console.WriteLine( "Task #{0}: Constructed!" , tsk1.Id); Task tsk2 = new Task(MyTask.T2); Console.WriteLine( "Task #{0}: Constructed!" , tsk1.Id); //运行Task tsk1.Start(); tsk2.Start(); //等待Task运行结束 WaitAll(tsk1, tsk2); Console.ReadLine(); } /// <summary> /// 等待所有的Task运行结束 /// </summary> /// <param name="tsks">等待的Task类</param> public static void WaitAll( params Task[] tsks) { foreach ( var t in tsks) { t.Wait(); } } } } |
运行结果
程序Ⅱ:通过TaskFactory启动任务并接收任务的返回值
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
39
40
41
|
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Test001 { class Program { /// <summary> /// Task类封装 /// </summary> class MyTask { /// <summary> /// 求1+2+...+n的和 /// </summary> /// <param name="n">数n</param> /// <returns></returns> public static int Sum( object n) { int x = ( int )n; int sum = 0; for ( int i = 1; i <= x; i++) { sum += i; } return sum; } } static void Main( string [] args) { Task< int > tsk = Task< int >.Factory.StartNew(MyTask.Sum, 100); Console.WriteLine( "Result is: " + tsk.Result); Console.ReadLine(); } } } |
运行结果
程序Ⅲ:通过Parallel类的Invoke函数,并行调用多个Task
本程序中通过Lambda表达式来建立新的Task
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
39
40
41
42
|
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace Test002 { class Program { static void Main( string [] args) { Parallel.Invoke ( () => { Console.WriteLine( "Task #{0}: Begin!" , Task.CurrentId); for ( int i = 0; i < 5; i++) { Thread.Sleep(1000); Console.WriteLine( "Task #{0}: {1}" , Task.CurrentId, i); } Console.WriteLine( "Task #{0}: Terminated!" , Task.CurrentId); }, () => { Console.WriteLine( "Task #{0}: Begin!" , Task.CurrentId); Thread.Sleep(500); for ( int i = 0; i < 5; i++) { Thread.Sleep(1000); Console.WriteLine( "Task #{0}: {1}" , Task.CurrentId, i); } Console.WriteLine( "Task #{0}: Terminated!" , Task.CurrentId); } ); Console.ReadLine(); } } } |
运行结果
程序Ⅳ:通过Parallel类的For和FoeEach函数,并行调用多个Task
本程序中,通过Stopwatch类统计程序段的运行时间
从例中可以看出:不是所有的循环在并行化时都是有效的。通常,对于小型循环或执行非常简单的操作的循环来说,使用顺序循环比并行循环更加快速
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Test003 { class Program { /// <summary> /// 示例函数 /// </summary> /// <param name="n">参数</param> public static void DoSomeThing( int n) { int sum = 0; for ( int i = 0; i < n * 100; i++) { sum += i; } } static void Main( string [] args) { //计时工具,需要System.Diagnostics Stopwatch sw = new Stopwatch(); //统计依次顺序调用函数的时间 sw.Start(); for ( int i = 100; i < 105; i++) { DoSomeThing(100); } sw.Stop(); Console.WriteLine( "TotalTime: {0}" , sw.Elapsed.TotalMilliseconds); sw.Reset(); Console.WriteLine( "===========" ); //统计并行调用函数的时间 sw.Start(); Parallel.For(100, 105, DoSomeThing); sw.Stop(); Console.WriteLine( "TotalTime: {0}" , sw.Elapsed.TotalMilliseconds); sw.Reset(); Console.WriteLine( "===========" ); //统计并行调用函数的时间 sw.Start(); Parallel.ForEach( new int [5] { 100, 101, 102, 103, 104 }, DoSomeThing); sw.Stop(); Console.WriteLine( "TotalTime: {0}" , sw.Elapsed.TotalMilliseconds); sw.Reset(); Console.ReadLine(); } } } |
运行结果
END
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通