置顶随笔
#
摘要: CCR介绍 API概览 Ports和PortSet 协调原语(Coordination Primitives) 任务调度 迭代器 失败处理 与非CCR代码互操作 其他的并发方法
阅读全文
2009年11月17日
#
CCR,并发与协调运行时(Concurrency and Coordination Runtime)。从名字里我们就可以知道,这个东东是用来简化并发程序设计的。为何要并发呢?因为我们有多个任务需要处理,如果能同时做就会充分利用硬件而减少处理的时间。自然的,CCR也是以“任务”为核心进行设计的,CCR中的代码也可以分为如下几个功能:描述任务、生成任务、调度任务和执行任务。
描述任务
对于计算机来说一个任务就是一段需要执行的代码,于是CCR有一个对任务的最抽象描述:ITask接口
任务被封装在ITask实例中,当CCR调度这个任务实例去执行之后,CCR会调用ITask.Execute方法来执行该任务。在ITask接口之下,派生出来各种各样的Task
本节讨论的是CCR的整体结构,后面我们会具体讨论这些classes。
生成任务
对于计算机来说,任务都是类似的:按给定的参数执行一个给定的方法。但是对于程序员来说,往往并非这么简单。从时序上来讲,任务可以分为这么几种情况:算法和参数都已经齐备的、已知算法等待参数的和已知参数等待算法的。对于第一种情况,直接使用Thread或者ThreadPool也可以很方便的解决问题,当然CCR也提供了相应的支持。对于后面两种情况,CCR使用了计算过程与参数分离描述的方法来解决。计算机的程序的作用就是处理流程相对固定的事务,往往计算逻辑是有限的而参数是变化无穷的。于是CCR将计算过程与参数分离开来,调用者不需要知道如何处理这些参数,甚至不需要知道是谁何时来进行处理,它只需要把要计算的数据发送到一个特定的地方即可,而这些数据会被可信赖的得以处理。当计算过程接收到适当的参数的时候,也就生成了任务。CCR中Port和PortSet类型就是这样的参数存储器。ReceiverTask及其子类则是封装计算过程的类型,Port可以被注册到相应的ReceiverTask中,当有其他用户向Port中投递元素时,就会生成任务并放入相应的DispatcherQueue中等待调度。
调度任务
需要执行的任务是有先来后到、轻重缓急的,同时计算机的CPU资源是有限度,每个核(包括超线程的逻辑核)在同一时间只能处理一个线程。这时候就需要进行一定的调度。为了充分利用CPU,自然是要使用多线程来执行任务。如果不使用CCR,我们也可以用.net内置的Thread和ThreadPool都可以用的并行任务调度,其中又数ThreadPool用起来比较简单,直接把要执行的方法丢进去就好了。但是这简单的背后也存在问题,虽然是解决了任务的先来后到,但是没办法分轻重缓急了,ThreadPool坚持认定CPU面前人人平等的原则,晚来的就是要侯着等先到底执行完。直接用Thread也有问题,就是无法很容易的控制线程的数量以及重用线程,而线程本身又是一个比较重型的资源,反反复复的创建和销毁很影响效率。为了解决这些问题CCR提出了自己的任务调度方案。DispatcherQueue。
DispatcherQueue本质上就是一个任务队列,它使得任务按照先来后到的顺序执行。但是你可以创建多个DispatcherQueue,比如把高优先级的任务放入一个队列,把普通优先级的放入另外一个,那么高优先级的任务不需要等待前面所有普通优先级任务都执行完毕才得到执行。
执行任务
Dispatcher是CCR的执行单元,也是一个线程池的实现。既然是线程池,那么就必然有它所要管理的工作线程,TaskExecutionWorker类封装了Dispatcher中工作线程所要执行的方法以及一些必要的处理。

2009年11月16日
#
由于CCR的源码并没有直接公开,所以我们需要借助一些工具来窥探它的秘密。
分析CCR需要如下的工具
MS Robotic Studio Express 2008R2,这个就不用解释了,安装它就是为了获得CCR
Reflector & FileDisassembler,Reflector有两个作用,一个是用来把CCR的dll文件反编译到C#语言,第二个是直接对CCR进行一些分析,而这些分析在VS中并不容易。FileDisassembler是Reflector的一个插件,用来把反编译的结果导出为一个C#工程。
Visual C# 2008 Express or Visual Studio 2010 beta2(推荐,因为VS 2010大大增强了多线程调试能力)
以上工具皆可合法的免费获得
CCR源码和例子程序
Microsoft.Ccr.Core.dll是我们本次要研究的对象。为了分析和调试的方便,我们需要把它用Reflector和FileDisassembler反编译。注意,反编译后的源码可能有些问题,下面记载了几个比较重要的修改:
1. Resource文件。我们需要先删除Reflector生成的Resource1.cs,然后新建一个名为Resource1.resx的资源文件,把Reflector生成的Microsoft.Ccr.Core.resx中的字符串全部复制到Resource1.resx中,最后删除原来的Microsoft.Ccr.Core.resx
2. Dispatcher.cs中有两个静态变量的初始化顺序不正确,需要吧TraceSwitchCore的声明和初始化语句放在文件最顶端。
Sample Code,为了统一起见,我选择了MSDN Mag中的这篇文章中的代码。
解压Sample Code后,用VS创建一个CCRDemo的project,把解压得到的代码添加到CCRDemo项目中,再把反编译得到的CCR源码工程也加入这个Solution中,最后给CCRDemo添加CCR的引用。如果能编译并运行CCRDemo,则说明我们的分析环境已经构建好了。
2009年10月29日
#
2009年10月18日
#
原文链接
去中心化软件服务(DSS)是一个基于CCR的轻量级.net运行时环境。DSS提供了一个轻量级的,状态导向的服务模型,它将REST概念和构造高性能高扩展性应用的系统级方法结合在一起。在DSS中服务被暴露为一种可以被程序和UI操作界面访问的资源。通过集成:状态隔离、结构化状态操作、事件通知和常规服务组合,DSS解决了编写运行在一个节点或者跨网络的高性能、可观察、松耦合的应用程序的需求。
DSS的主要设计目标是将性能、简单性和强壮性结合在一起。这使得DSS非常适合于创建由服务聚合而成的应用,无论服务是运行在同一个节点还是跨越网络。这个目标使得DSS成为一个灵活且简单的可以用于编写多种应用的平台。DSS使用去中心化服务协议(
Decentralized Software Services Protocol (DSSP))和HTTP协议作为服务间交互的基础。DSSP是一种轻量级的基于SOAP的协议,它提供了一个清晰、对称(symmetric)支持状态操作的状态转移应用程序模型和一个由状态变化驱动的事件模型。
DSS运行时提供了一个宿主环境(hosting environment),这个环境提供了内建的在同一个节点和跨越网络的对服务组合、发布/订阅、生命周期管理、安全、监控、日志等的支持。服务可以使用Visual Studio编写,也可以使用Microsoft Visual Programming Language(VPL)来编写。VPL可以通过简单的托拽服务到画布上,然后根据数据依赖关系把服务连接到一起来创建简单的服务组合应用。另外,DSS清单编辑器(DSS manifest editor)提供了一个图形化环境来连接(wiring up)、配置、部署和在一个节点或跨越网络运行DSS应用程序。
DSS覆盖的问题领域
下面我们讨论三个常见的应用程序设计的问题领域,以及DSS如何来解决它们:
强壮性
在任何负责的系统中,系统一个部分的失败都有导致整个系统瘫痪的可能。这是因为部分失败如果不能被正确的隔离、检测和处理,将会导致灾难性的失败。松耦合是一种常见的用于限制部分失败影响的设计模式。然而,为了构造松耦合的系统,每个组件必须与其他组件隔离,并且与底层运行环境隔离。在系统失败中两种常见的隔离方法是数据隔离和运行隔离。缺少数据隔离会导致服务的内部状态被破坏,而缺少运行隔离则会导致组建失去响应。DSS同时在数据和运行上隔离服务。数据隔离是通过完整克隆所有服务(包括系统服务)间交换的消息来实现的。克隆代码作为编译的一部分来生成,它比完整序列化的速度快很多。
可组合性
强壮性的需求强制要求程序成为一批松耦合组件的组合。这引发了另外一个问题:如何识别、定位以及把这些组件组合到一个正在运行的应用程序中。大多数传统的系统把一个应用定义为一个单一的进程而不是一组共同工作的松耦合服务的组合,这就把组合的任务留给了应用的设计者。DSS提供了协议和运行时来支持创建、管理、部署和运行由松耦合服务组合而成的应用。服务在运行时被创建,并且为了功能的正确,根据它需要组合的其他服务的描述进行连接。这个模型允许应用程序在运行时配置每个服务的实力在哪里运行。而且,由于每个服务实例与其他服务实例的关系都可以通过DSSP暴露出来,这使得看到任意指定的服务实例所依赖的服务实例成为可能。
可观察性
所有应用程序的一个重要的方面是:可以知道它正在做什么,它处于什么状态,以及它如何到达这个状态。简单的说:一个没有办法观测的系统就不可能知道它是否功能正常。通过将一个服务定义为一个由URI表达的资源标识以及暴露这个资源的状态(可能被服务内部行为或者通过与其他服务交互改变),DSS将可观察性概念放置于它应用程序模型的核心。然而,可观察性概念超越了只是通过侦测服务的状态来监控应用程序。通过根据服务的状态统一的暴露服务,DSS为处理管理、安全和基于状态操作的服务组合提供了简单且一致的解决方案。DSS还使得每个DSS服务都可以通过浏览器UI进行访问,以及非常容易的与各种常用的工具和平台集成。
起步
作为DSS的一部分,我们提供了大量不同的例子和指导,它们演示的范围涵盖了从开始编写“Hello world”之类的简单应用到可以平滑的运行在同一个节点或者跨越网络的复杂应用。
2009年9月22日
#
今天翻阅msdn时看到一个概念
Domain Neutral Assemblies,虽然这个咚咚的名字字面意思挺清楚,但是之前从未接触过,于是特意搜索了一番,东拉西扯之下,也学到了一些关于App Domain的有趣的东西,在这里总结记录一下。
首先,App Domain是什么?MSDN里给出了一堆文字来说明。其实简单的说,App Domain就是是一个轻量级的进程。
- Domain Neutral Assemblies
顾名思义,Domain Neutral Assemblies就是不跟特定App Domain相关而可以跨越多个App Domains的Assembly。大家都知道,一般情况下,我们自己创建App Domain都是为了动态的加载/卸载一些Assemblies,但是Domain Neutral Assemblies比较特殊,它是不能随着App Domain被unload的。而且处于性能的考虑,Domain Neutral Assemblies只会被JIT一次,JIT之后的代码会存储在Share Domain中。但是Assemblies相关的数据依然会存储在每个加载它的App Domains中。例如:某个Application中有几个App Domains,而Assembly A被作为一个Domain Neutral Assembly加载。A中有一个类型T,T有一个静态变量S,那么T.S在每个App Domain中的值是分别存储的,修改一个App Domain中的T.S不会改变另一个App Domain中的T.S。
就像C++中的friend classes,在.net 2.0中引入了friend assemblies。通过给Assembly A设置InternalsVisibleToAttribute属性来设置B是A的Friend Assembly。这样B中的类型就可以访问A中的internal类型和internal成员(方法/属性/子段/事件等)。
- 如何加载Assemblies到一个App Domain
.net提供了多种方法加载一个Assembly到App Domain,但是推荐使用Assembly.Load方法来做这件事。剩下的方法还有:Assembly.LoadFrom, Assembly.ReflectionOnlyLoad, Assembly.ReflectionOnlyLoadFrom。还有一些看起来跟加载Assembly无关的方法,其实也有加载Assembly的副作用,比如Type.GetType, AppDomain.CreateInstance, AppDomain.CreateInstanceAndUnwrap。
比较特别的一个方法是AppDomain.Load,这个方法是不推荐在Managed Code中调用的。因为如果你在App Domain A中调用了App Domain B的Load方法,B.Load其实是将Assembly加载到了App Domain B中,这还不是最糟糕的,最糟糕的是,AppDomain的Load方法会返回Assembly的引用到A,还记得吧,App Domain之间是隔离的,A并不能直接调用B中的方法和类型而是要通过Marshal的方式来通讯,但是由于Assembly不是从MarshalByRef继承,所以Assembly对象必须以Marshal by value的方式返回到A中,这时A会再次根据自己的配置来定位和加载这个Assembly,最好的情况下就是B和A都加载了这个Assembly,如果运气不好,A和B设置的搜索路径不同而A恰好找不到这个Assembly,boom,一个FileNotFoundException就被抛出啦。
通过Assembly的ReflectionOnlyLoad/ReflectionOnlyLoadFrom方法可以把一个Assembly加载到Reflection-Only context中,顾名思义,在这个上下文中的Assembly只能用于反射而不能用于执行。通过这个方法可以加载不同CLR版本的Assembly,我想著名的Reflector应该就是用的这种办法吧。唯一一个例外就是mscorlib,即使用ReflectionOnlyLoad也是无法加载不同CLR版本的mscorlib。
参考资料:
http://blogs.msdn.com/junfeng/archive/2004/08/05/208375.aspx
http://blogs.msdn.com/cbrumme/archive/2003/06/01/51466.aspx
http://msdn.microsoft.com/en-us/library/43wc4hhs.aspx
2009年2月18日
#
摘要: Directory Purpose /etc System configuration files are stored here. /bin This directory holds binaries that must be accessible at all times and that ordinary users are likely to run. /sbin This dir...
阅读全文
2009年1月10日
#
摘要: http://www.codeproject.com/KB/cs/FastMethodInvoker.aspxhttp://www.cnblogs.com/JeffreyZhao/archive/2008/11/22/invoke-method-by-lambda-expression.htmlhttp://www.codeproject.com/KB/cs/FastMethodInvoker.a...
阅读全文
2008年10月10日
#
摘要: 安装说明确实写的很清楚很详细,没有什么其他的,唯一需要注意一点就是安装顺序。如果在安装TFS 2008之前安装了任何其他VS 2008的相关产品,请卸载。然后再安装TFS 2008、TFS 2008 SP1之后再安装VS2008。否则会报一个Error 200082的莫名其妙的错误。
阅读全文
2008年3月19日
#
摘要: 暂记下提纲,培训完回来慢慢写。1. 设置2. 下断点3. 查看进程信息4. 查看线程调用栈(Native&Managed)5. 查看Managed内存
阅读全文
2008年2月16日
#
摘要: 安装了MySQL Connector/Net 5.20之后在VS2008中新建连接,居然直接报告错误 Package Load Failure Package 'MySQL Connector Net 5.2.0' has failed to load properly ( GUID = {79A115C9-B133-4891-9E7B-242509DAD272} ). Please conta...
阅读全文