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();
            }
        }
             
    }
}

  

 

posted @   路途遥远  阅读(2668)  评论(1编辑  收藏  举报
编辑推荐:
· 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 - 安装
点击右上角即可分享
微信分享提示