C# 并行开发总结
本文内容 均参考自 《C#并行高级编程》
TPL 支持 数据并行(有大量数据要处理,必须对每个数据执行同样的操作, 任务并行(有好多可以并发运行的操作),流水线(任务并行和数据并行的结合体)
在.net 4.0 引入新的 Task Parallel Library 处理 并行开发 。
Parallel类
关键词 :
Parallel.For and Parallel.Foreach - 负载均衡的多任务
Parallel.Invoke - 并行运行多任务
ParallelOptions - 指定最大并行度 (实例化一个类并修改MaxDegreeOfParallelism 属性的值 )
Environment.ProcessorCount - 内核最大数
命令式任务并行
关键词 : Task类 , 一个task 类表示一个异步操作 (需要考虑到任务的开销)
启动任务使用Task类的Start 方法 , 等待线程完成使用WaitAll 方法 , 通过CancellationTokenSource 的Cancel方法来 中断 Task的运行
怎样表达任务间的父子关系 ? TaskCreationOption的AttachToParent来完成
怎样来表达串行任务 ? Task.ContinueWith
并发集合
BlockingCollection
ConcurrentDictionary/ConcurrentQueue/ConcurrentStack
下面来一个例子是实操 C# 多任务并发。
场景 : 主进程 打开 一个 生产者线程 和 一个消费线程 。 他们之间可以相互对话, 如([动词,名词]) say,hello task,a . 生产者说一句话 消费者听, 消费者或应答或提交新的任务或结束自己。
代码
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 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | using System; using System.Threading; using System.Threading.Tasks; using System.Collections.Concurrent; namespace TPLTest { class Program { public static readonly int MAX_DATA_LENGTH = 256; private static BlockingCollection<Message> bcstr = new BlockingCollection<Message>(MAX_DATA_LENGTH) ; public static readonly string SAY_THANKS = "thanks" ; public static readonly string SAY_WELCOME = "welcome!" ; public static readonly string BYE = "bye" ; public static readonly string SAY = "say" ; public static readonly string TASK = "task" ; public static readonly string TIMEOUT = "timeout" ; public static readonly string ONLINE = "ONLINE" ; public static readonly string WHAT = "What?" ; public static readonly int WAIT = 20000; public static void Main( string [] args) { //消费者线程 ParallelOptions po = new ParallelOptions(); po.MaxDegreeOfParallelism = -1; Parallel.Invoke(po,() => { int selfID = Environment.CurrentManagedThreadId; Message customer = new Message(); customer.CustomerThreadID = selfID ; customer.content = ONLINE; Console.WriteLine(customer.ToString( false )); while ( true ){ if (bcstr.TryTake( out customer, WAIT)) { customer.CustomerThreadID = selfID ; customer.doAction(); Console.WriteLine( " " ); Console.WriteLine(customer.ToString( false )); if (customer.endThread()){ break ; } } else { if (customer == null ) { customer = new Message(); } customer.CustomerThreadID = selfID ; customer.content = TIMEOUT; Console.WriteLine(customer.ToString( false )); } } }, () => { int prdID = Environment.CurrentManagedThreadId; Message productor = new Message(); productor.ProductorThreadID = prdID; productor.content = ONLINE; Console.WriteLine(productor.ToString( true )); while ( true ){ Console.Write( "Productor Behavior (i.e. say,hello) : " ); string msgContent = Console.ReadLine(); productor = new Message(); productor.ProductorThreadID = prdID; productor.key = msgContent.Split( ',' )[0]; productor.content = msgContent.Split( ',' )[1]; bcstr.Add(productor); if (productor.endThread()) { break ; } } }); } } class Message { public int ProductorThreadID { get ; set ;} public int CustomerThreadID { get ; set ;} public string key { get ; set ;} public string content{ get ; set ;} public bool endThread() { return string .Compare(key, Program.BYE) == 0; } public string ToString( bool isProductor){ return string .Format( "{0} Thread ID {1} : {2}" , isProductor ? "Productor" : "Customer" , isProductor ? ProductorThreadID.ToString() : CustomerThreadID.ToString(), content); } public void doAction(){ if ( string .Compare(key, Program.SAY) == 0) { content = string .Compare(content, Program.SAY_THANKS) == 0 ? Program.SAY_WELCOME : Program.WHAT; } if ( string .Compare(key, Program.TASK) == 0) { Task taskA = Task.Factory.StartNew(() => { Console.WriteLine( "task A begin " ); Task ChildOfFatehrA = Task.Factory.StartNew(() => { Console.WriteLine( "Sub task A begin " ); Thread.Sleep(1000); Console.WriteLine( "Sub task A end " ); }); ChildOfFatehrA.Wait(); Console.WriteLine( "task A end " ); }); taskA.ContinueWith(taskB => { Console.WriteLine( "task B begin " ); Thread.Sleep(5000); Console.WriteLine( "task B end " ); }); taskA.Wait(); } } } } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
2013-12-06 ios专题 - CocoaPods - 初次体验
2013-12-06 ios专题 - CocoaPods - 安装