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

	}
}

  

时间: 2024-11-10 07:40:07

C# 并行开发总结的相关文章

【翻译】CEDEC2014跨世代多平台并行开发PS4版如龙维新开发的一年

本篇PPT讲述的是如龙4的开发过程中,集中在PS3和PS4并行开发中所遇到和解决的一些问题.如64位指针,DX9向DX11移植API的问题,以及在PS4上使用并行渲染在1080P下让FPS达到60等.涉及的实际技术并不是多也不新,不过对家用机有兴趣的朋友可以也可以稍微了解下. 下载地址: 链接: http://pan.baidu.com/s/1hqy3tWS 密码: jlf8 西川善司对这篇PPT也有一个解说版,链接在这里,如果有兴趣的可以看看再来讨论. http://www.4gamer.ne

.NET下的并行开发(案例代码)

以下主要是通过一个报表处理程序来说明并行开发的方式.对于数据冲突和共享,可以通过对象数组解决.设计到并行的核心代码已用红色标出.在并行程序的处理上,需要把原来串行的子公司变成一个一个类的对象,让所有的类对象一起并行运行就达到提高响应速率的目的了.并行设计中,主要的还是编程的思想,并行的语法,规则都是规划好的.好的工具就看你如何使用了. using System;using System.Data;using System.Configuration;using System.Collection

并行开发——Parallel的使用 -摘自网络

随着多核时代的到来,并行开发越来越展示出它的强大威力,像我们这样的码农再也不用过多的关注底层线程的实现和手工控制, 要了解并行开发,需要先了解下两个概念:“硬件线程”和“软件线程”. 1. 硬件线程 相信大家手头的电脑都是双核以上的,像我这样古董的电脑都是双核的,这样的双核叫做物理内核. 硬件线程又叫做逻辑内核,我们可以在”任务管理器“中查看”性能“标签页,如下图,我们知道有2个硬件线程. 一般情况下,一个物理内核对应一个逻辑内核,比如我这里的2对2.当然如果你的cpu采用的是超线程技术,那么可

.NET下的并行开发

并行开发一直是程序员在开发项目中遇到的一道坎,但为了迎合硬件的升级,面对高端多核的处理器,并行编程势在必行.在.NET平台下的开发支持并行模式,下面用一个实际项目说明并行的高效率和神奇之处. 在优化中国铁建企业经营管理系统时,遇到一个迫切需要解决的问题.就是报表处理响应时间的问题,在系统最初数据较少,导出报表响应时间较快.但是随着数据的不断扩充,就一个分局的数据导出(大概600条)也需要5分钟左右,当然这个和电脑的配置相关.若是总股份公司的项目报表导出(6000条左右),那个时间在普通的电脑上根

Win7下搭建JAVA并行开发环境MPJ Express(PART1)

在Winindows 7 中快速搭建JAVA并行开发环境MPJ Express及其中可能遇到的各种问题解析(PART1) MPJ Express是一个线程安全的Java版本的并行消息传递库,它提供了mpiJava 1.2 API规范的完整实现.MPJ Express实现了MPJ库中的两种通信设备,第一种叫niodev,基于Java NIO包.第二种叫mxdev,基于Myrinet eXpress库. 基于这个消息库,用户即可使用JAVA作为编程语言来开发并行程序.特别是随着高性能平台的普及,面对

Win7下搭建JAVA并行开发环境MPJ Express(PART2)

在上一节中,我们已经成功在Windows中搭建了基于MPJ Express的并行开发环境,本部分我们将在Eclipse中编写一个简单的程序来试用一下刚刚搭建的环境. 首先在Eclipse中创建一个Project,如下图所示. 输入项目名称MyMPJExpress或者mpjExpress(可以任取),然后单击"Finish"按钮. 在已经创建好的项目中,新建一个Class,如下所示. 输入类的名称,例如Hellworld或者mpjHelloWorld(可以任取),然后单击"Fi

8天玩转并行开发——第一天 Parallel的使用

转自:http://www.cnblogs.com/huangxincheng/archive/2012/04/02/2429543.html 随着多核时代的到来,并行开发越来越展示出它的强大威力,像我们这样的码农再也不用过多的关注底层线程的实现和手工控制, 要了解并行开发,需要先了解下两个概念:“硬件线程”和“软件线程”. 1. 硬件线程 相信大家手头的电脑都是双核以上的,像我这样古董的电脑都是双核的,这样的双核叫做物理内核.

并行开发学习随笔1——plinq并行

这两天在看园友的文章 <8天玩转并行开发——第三天 plinq的使用> 对里面的第一个实例亲手实践了一下,发现了一点有意思的事情. 测试环境:.net 4.5 64位(如果是32位的,测试千万数据时会爆出out of memory的错误) 在我的机器上,千万数据的测试结果: 百万数据的测试结果: 十万数据的测试结果: 可以看出,到底使用串行还是并行应该根据数据量来决定,两者的大致就在几十万数据的时候性能基本接近.当然这个结果不是固定的,应该是与机器的配置以及测试时的系统环境有比较大的关系,实际

Win7下搭建JAVA并行开发环境MPJ Express(PART3)

在前面的两个PART中,我们分别搭建了并行开发环境,并小试牛刀实践了简单的并行开发. Win7下搭建JAVA并行开发环境MPJ Express(PART1) http://baimafujinji.blog.51cto.com/907111/1629153 Win7下搭建JAVA并行开发环境MPJ Express(PART2) http://baimafujinji.blog.51cto.com/907111/1629176 当然在这个过程中,出现这样或那样的问题是在所难免的,这一部分我们就来讨

8天玩转并行开发——第七天 简要分析任务与线程池

原文:8天玩转并行开发--第七天 简要分析任务与线程池 其实说到上一篇,我们要说的task的知识也说的差不多了,这一篇我们开始站在理论上了解下“线程池”和“任务”之间的关系,不管是 说线程还是任务,我们都不可避免的要讨论下线程池,然而在.net 4.0以后,线程池引擎考虑了未来的扩展性,已经充分利用多核微处理器 架构,只要在可能的情况下,我们应该尽量使用task,而不是线程池. 首先看一下task的结构 从图中我们可以看出Task.Factory.StartNew()貌似等同于用ThreadPo