• 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  .   生产者说一句话 消费者听, 消费者或应答或提交新的任务或结束自己。  

    代码 

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

      

  • 相关阅读:
    移植ssh到mini2440
    VMware中Ubuntu安装VMware Tools步骤及问题解决方法
    Linux的网卡由eth0变成了eth1,如何修复
    mini2440移植所有驱动到3.4.2内核详细解说
    单片机的一生(感觉在说大部分人)
    mini2440移植linux-3.4.2内核详细解说
    Ubuntu中恢复桌面的上下默认面板命令
    mini2440移植最新u-boot-2012.04.01详细解说
    MyEclipse CI 2018.8.0 官方最新免费版(破解文件+激活工具+破解教程)
    cocos 获取一个骨骼动画多次显示播放
  • 原文地址:https://www.cnblogs.com/luoguoqiang1985/p/6136206.html
Copyright © 2020-2023  润新知