<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_Technological achievements dream</title><subtitle type="text">技术成就梦想</subtitle><id>http://feed.cnblogs.com/blog/u/33262/rss</id><updated>2012-02-08T13:46:27Z</updated><author><name>Henry Cui</name><uri>http://www.cnblogs.com/Henllyee/</uri></author><generator>CNBlogs BlogServer</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Henllyee/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/33262/rss"/><entry><id>http://www.cnblogs.com/Henllyee/archive/2012/02/08/Html5_First.html</id><title type="text">HTML 5 Step by Step(一) 拖放API</title><summary type="text">在Html4中，我们可以通过监听mousedown、mousemove、mouseup来实现拖放效果。在Html5中，直接提供了支持拖放操作的API，我们可以很简单的几步就可以实现拖放的效果。 实现的概要 首先我们了解下跟拖动相关的事件： 事件 产生的源对象 说明 dragstart 被拖动的元素 开始拖放动作 drag 被拖动的元素 拖放过程中 dragenter ...</summary><published>2012-02-08T13:44:00Z</published><updated>2012-02-08T13:44:00Z</updated><author><name>Henry Cui</name><uri>http://www.cnblogs.com/Henllyee/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Henllyee/archive/2012/02/08/Html5_First.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Henllyee/archive/2012/02/08/Html5_First.html"/><content type="html">&lt;p&gt;在Html4中，我们可以通过监听mousedown、mousemove、mouseup来实现拖放效果。在Html5中，直接提供了支持拖放操作的API，我们可以很简单的几步就可以实现拖放的效果。&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;实现的概要&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;首先我们了解下跟拖动相关的事件：&lt;/p&gt;  &lt;table border="1" cellspacing="0" cellpadding="2" width="701"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="114"&gt;事件&lt;/td&gt;        &lt;td valign="top" width="286"&gt;产生的源对象&lt;/td&gt;        &lt;td valign="top" width="299"&gt;说明&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="114"&gt;dragstart&lt;/td&gt;        &lt;td valign="top" width="286"&gt;被拖动的元素&lt;/td&gt;        &lt;td valign="top" width="299"&gt;开始拖放动作&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="114"&gt;drag&lt;/td&gt;        &lt;td valign="top" width="286"&gt;被拖动的元素&lt;/td&gt;        &lt;td valign="top" width="299"&gt;拖放过程中&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="114"&gt;dragenter&lt;/td&gt;        &lt;td valign="top" width="286"&gt;拖动过程中鼠标经过的元素&lt;/td&gt;        &lt;td valign="top" width="299"&gt;被拖动的元素开始进入本元素的范围内&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="114"&gt;dragleave&lt;/td&gt;        &lt;td valign="top" width="286"&gt;拖动过程中鼠标经过的元素&lt;/td&gt;        &lt;td valign="top" width="299"&gt;被拖动的元素离开本元素的范围&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="114"&gt;drop&lt;/td&gt;        &lt;td valign="top" width="286"&gt;拖放的目标元素&lt;/td&gt;        &lt;td valign="top" width="299"&gt;有其他元素拖动到了本元素中&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="114"&gt;dragend&lt;/td&gt;        &lt;td valign="top" width="286"&gt;拖动的对象元素&lt;/td&gt;        &lt;td valign="top" width="299"&gt;拖动结束&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="114"&gt;dragover&lt;/td&gt;        &lt;td valign="top" width="286"&gt;拖动过程中鼠标经过的元素&lt;/td&gt;        &lt;td valign="top" width="299"&gt;被拖动的元素在本元素上移动&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;实现步骤：&lt;/p&gt;  &lt;p&gt;1.我们要想一个元素可以被拖动，同时需要将元素的draggable属性设置为true（img、a默认允许拖放）；&lt;/p&gt;  &lt;p&gt;2.监听拖动相关的事件。&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Demo&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;我们实现一个将几个商品拖入的购物车的一个简单Demo，效果如下：&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Henllyee/201202/201202082144163922.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Henllyee/201202/201202082144174611.png" width="217" height="314" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;首先看下Html代码：&lt;/p&gt;  &lt;pre &gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;body &lt;/span&gt;&lt;span style="color: red"&gt;onload&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;init()&amp;quot;&amp;gt;&#xD;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;span&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;商品列表&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;span&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;goodsList&amp;quot;&amp;gt;&#xD;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;goods&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;draggable&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;true&amp;quot;&amp;gt;&#xD;
            &lt;/span&gt;ThinkPad T410i&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;goods&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;draggable&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;true&amp;quot;&amp;gt;&#xD;
            &lt;/span&gt;Ipad 2&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;span&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;已选商品：&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;span&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;box&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;style&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;: 200px; &lt;/span&gt;&lt;span style="color: red"&gt;height&lt;/span&gt;&lt;span style="color: blue"&gt;: 200px; &lt;/span&gt;&lt;span style="color: red"&gt;border&lt;/span&gt;&lt;span style="color: blue"&gt;: 1px solid green;&amp;quot;&amp;gt;&#xD;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;body&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;Javascirpt:&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;&lt;span style="color: blue"&gt;          function &lt;/span&gt;init() {&#xD;
            &lt;span style="color: blue"&gt;var &lt;/span&gt;goodsList = getElementsbyClassName(&lt;span style="color: maroon"&gt;'goods'&lt;/span&gt;);&#xD;
            &lt;span style="color: blue"&gt;var &lt;/span&gt;box = document.getElementById(&lt;span style="color: maroon"&gt;'box'&lt;/span&gt;);&#xD;
            &lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;i = 0; i &amp;lt; goodsList.length; i++) {&#xD;
                goodsList[i].addEventListener(&lt;span style="color: maroon"&gt;'dragstart'&lt;/span&gt;, &lt;span style="color: blue"&gt;function &lt;/span&gt;(ev) {&#xD;
                    &lt;span style="color: blue"&gt;var &lt;/span&gt;dt = ev.dataTransfer;&#xD;
                    dt.effectAllowed = &lt;span style="color: maroon"&gt;'all'&lt;/span&gt;;&#xD;
                    dt.setData(&lt;span style="color: maroon"&gt;'text/plain'&lt;/span&gt;, &lt;span style="color: blue"&gt;this&lt;/span&gt;.textContent);&#xD;
                }, &lt;span style="color: blue"&gt;false&lt;/span&gt;);&#xD;
            }&#xD;
            box.addEventListener(&lt;span style="color: maroon"&gt;'dragend'&lt;/span&gt;, &lt;span style="color: blue"&gt;function &lt;/span&gt;(ev) {&#xD;
                ev.preventDefault();&#xD;
            }, &lt;span style="color: blue"&gt;false&lt;/span&gt;);&#xD;
            box.addEventListener(&lt;span style="color: maroon"&gt;'drop'&lt;/span&gt;, &lt;span style="color: blue"&gt;function &lt;/span&gt;(ev) {&#xD;
                &lt;span style="color: blue"&gt;var &lt;/span&gt;dt = ev.dataTransfer;&#xD;
                &lt;span style="color: blue"&gt;var &lt;/span&gt;goodsName = dt.getData(&lt;span style="color: maroon"&gt;'text/plain'&lt;/span&gt;);&#xD;
                box.textContent += goodsName;&#xD;
                ev.preventDefault();&#xD;
                ev.stopPropagation();&#xD;
            }, &lt;span style="color: blue"&gt;false&lt;/span&gt;);&#xD;
        }&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;解释下上面的代码：&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;1.获取class为goods的元素，在dragstart的时候，将自己本元素的textContext传递给dataTransfer（下面会说明dataTransfer对象的作用）；&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;2.在将goods拖动到box时候，获取dataTransfer数据，并显示出来；&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;3.preventDefault的作用是，对于目标元素，默认的情况下是不允许接收元素的，所以必须在dragend或则dragover事件内调用preventDefault。&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;关于DataTransfer对象&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;我们通过上面的例子知道拖动时是通过DataTransfer来进行拖动元素之间的数据传递的，同时我们也可以通过设置DataTansfer里面的相关属性来实现一些拖动的额外效果。下面看下DataTransfer的属性与方法：&lt;/p&gt;&#xD;
&#xD;
&lt;table border="1" cellspacing="0" cellpadding="2" width="752"&gt;&lt;tbody&gt;&#xD;
    &lt;tr&gt;&#xD;
      &lt;td valign="top" width="251"&gt;属性/方法&lt;/td&gt;&#xD;
&#xD;
      &lt;td valign="top" width="499"&gt;作用&lt;/td&gt;&#xD;
    &lt;/tr&gt;&#xD;
&#xD;
    &lt;tr&gt;&#xD;
      &lt;td valign="top" width="251"&gt;dropEffect属性&lt;/td&gt;&#xD;
&#xD;
      &lt;td valign="top" width="499"&gt;拖放操作的视觉效果，可以指定为none、copy、link、move&lt;/td&gt;&#xD;
    &lt;/tr&gt;&#xD;
&#xD;
    &lt;tr&gt;&#xD;
      &lt;td valign="top" width="251"&gt;effectAllowed属性&lt;/td&gt;&#xD;
&#xD;
      &lt;td valign="top" width="499"&gt;指定当元素被拖放时所允许的视觉效果&lt;/td&gt;&#xD;
    &lt;/tr&gt;&#xD;
&#xD;
    &lt;tr&gt;&#xD;
      &lt;td valign="top" width="251"&gt;types属性&lt;/td&gt;&#xD;
&#xD;
      &lt;td valign="top" width="499"&gt;存入数据的种类&lt;/td&gt;&#xD;
    &lt;/tr&gt;&#xD;
&#xD;
    &lt;tr&gt;&#xD;
      &lt;td valign="top" width="251"&gt;cleraData(DomString format)&lt;/td&gt;&#xD;
&#xD;
      &lt;td valign="top" width="499"&gt;清楚DataTransfer对象中存放的数据&lt;/td&gt;&#xD;
    &lt;/tr&gt;&#xD;
&#xD;
    &lt;tr&gt;&#xD;
      &lt;td valign="top" width="251"&gt;setData(DOMString format,DomString data)&lt;/td&gt;&#xD;
&#xD;
      &lt;td valign="top" width="499"&gt;存入数据&lt;/td&gt;&#xD;
    &lt;/tr&gt;&#xD;
&#xD;
    &lt;tr&gt;&#xD;
      &lt;td valign="top" width="251"&gt;DOMString getData(DOMString format)&lt;/td&gt;&#xD;
&#xD;
      &lt;td valign="top" width="499"&gt;从DataTransfer对象中读取数据&lt;/td&gt;&#xD;
    &lt;/tr&gt;&#xD;
&#xD;
    &lt;tr&gt;&#xD;
      &lt;td valign="top" width="251"&gt;setDragImange(Element image，long x,long y)&lt;/td&gt;&#xD;
&#xD;
      &lt;td valign="top" width="499"&gt;用img元素来设置拖放图标&lt;/td&gt;&#xD;
    &lt;/tr&gt;&#xD;
  &lt;/tbody&gt;&lt;/table&gt;&#xD;
&#xD;
&lt;p&gt;这里有几个要说明的：&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;1.现在拖动处理所支持的MIME类型为以下几种：&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;text/plain:文本文字；&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;text/html:HTML文字；&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;text/xml:xml；&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;text/uri-list:url列表。&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;对于dropEffect、effectAllowed属性使用的几个注意的地方：&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;一般的时候我们在ondragstart事件中去设置effectAllowed值，在ondragover事件中指定dropEffect值。其中如果effectAllowed属性设置为none，则不允许拖动，如果dropEffect属性设置为none，则不允许拖放到目标元素中。&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;总结&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;通过本篇Post，了解了Html5中拖放的新的API，比起html4实现起来要简单很多。下面的文章会继续一步步学习Html5其他方面的相关特性。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/Henllyee/aggbug/2343253.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Henllyee/archive/2012/02/08/Html5_First.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/Henllyee/archive/2012/02/02/Git_Firt.html</id><title type="text">Git学习笔记（一）初识Git</title><summary type="text">Git/GitHub已经火爆很长时间了，我已经落伍了。不管怎样现在学习也不为晚，今年也争取走出.Net，看看外面的世界。 安装Git 这里只在Window下进行的，首先从这里下载Git.exe。下载完成后，然后就进行Next、Next、Next… 生成SSH 安装完成后，进行SSH的生成跟设置，打开“Git Bash” 1.判断是否已经创建了ssh: $ cd ~/.ssh 第一次安装完，一般提示为No. 2.生成ssh $ ssh-keygen -t rsa -C henllyee@126.com 这里使用您自己的邮箱 默认会生成id_dsa.pub文件在C:\Use...</summary><published>2012-02-02T12:38:00Z</published><updated>2012-02-02T12:38:00Z</updated><author><name>Henry Cui</name><uri>http://www.cnblogs.com/Henllyee/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Henllyee/archive/2012/02/02/Git_Firt.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Henllyee/archive/2012/02/02/Git_Firt.html"/><content type="html">&lt;p&gt;Git/GitHub已经火爆很长时间了，我已经落伍了。不管怎样现在学习也不为晚，今年也争取走出.Net，看看外面的世界。&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;安装Git&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;这里只在Window下进行的，首先从这里&lt;a href="http://code.google.com/p/msysgit/downloads/list"&gt;下载&lt;/a&gt;Git.exe。下载完成后，然后就进行Next、Next、Next…&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;生成SSH&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;安装完成后，进行SSH的生成跟设置，打开“Git Bash” &lt;/p&gt;  &lt;p&gt;1.判断是否已经创建了ssh:&lt;/p&gt;  &lt;p&gt;$ cd ~/.ssh&lt;/p&gt;  &lt;p&gt;第一次安装完，一般提示为No.&lt;/p&gt;  &lt;p&gt;2.生成ssh&lt;/p&gt;  &lt;p&gt;$ ssh-keygen -t rsa -C &lt;a href="mailto:henllyee@126.com"&gt;henllyee&lt;em&gt;@126.com&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;这里使用您自己的邮箱&lt;/p&gt;  &lt;p&gt;默认会生成id_dsa.pub文件在C:\Users\YourUserName\.ssh&lt;/p&gt;  &lt;p&gt;3.将ssh key 跟Git Hub联系起来&lt;/p&gt;  &lt;p&gt;点击“Account Setting”&lt;a href="http://images.cnblogs.com/cnblogs_com/Henllyee/201202/201202022038207768.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Henllyee/201202/201202022038204213.png" width="146" height="75" /&gt;&lt;/a&gt;，选择&lt;a href="http://images.cnblogs.com/cnblogs_com/Henllyee/201202/201202022038207277.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Henllyee/201202/201202022038212327.png" width="244" height="53" /&gt;&lt;/a&gt;，点击&amp;quot;Add another public key &amp;quot;,将刚才生成的文件里面的内容拷贝到Key中。&lt;/p&gt;  &lt;p&gt;4.测试是否可以连接上Github&lt;/p&gt;  &lt;p&gt;$ ssh -T &lt;a href="mailto:git@github.com"&gt;git@github.com&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;提示以下信息表示OK.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Henllyee/201202/201202022038211804.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Henllyee/201202/201202022038219328.png" width="646" height="64" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;到这里，我们的SSH Key就生成完成了。这步的主要作用是，机器上的Git要跟GitHub进行连接必须要进行身份认证，ssh key即身份认证的凭证。&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;设置自己的用户信息&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;1.设置用户名称和邮箱信息&lt;/p&gt;  &lt;p&gt;$ git config --global user.name &amp;quot;&lt;em&gt;Firstname Lastname&lt;/em&gt;&amp;quot;&lt;/p&gt;  &lt;p&gt;$ git config --global user.email &amp;quot;&lt;em&gt;your_email@youremail.com&lt;/em&gt;&amp;quot;&lt;/p&gt;  &lt;p&gt;2.设置Token&lt;/p&gt;  &lt;p&gt;为了在一些其他工具使用git的时候并没有没有ssh key，这个时候需要我们配置我们的API token。在Account Setting里面选择“Account Admin”，可以找到我们的Token信息。&lt;/p&gt;  &lt;p&gt;$ git config --global github.user &lt;em&gt;username&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;$ git config --global github.token yourtoken&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;创建第一个Repository&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;1.创建Repository&lt;/p&gt;  &lt;p&gt;点击“New repository”&lt;a href="http://images.cnblogs.com/cnblogs_com/Henllyee/201202/201202022038222393.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Henllyee/201202/201202022038221903.png" width="244" height="45" /&gt;&lt;/a&gt;,这里我们取名Repository名字为“Test”.&lt;/p&gt;  &lt;p&gt;2.创建本地项目&lt;/p&gt;  &lt;pre&gt;$ mkdir Test&lt;/pre&gt;&#xD;
&#xD;
&lt;pre&gt;创建 “Test”目录&lt;/pre&gt;&#xD;
&#xD;
&lt;pre&gt;$ cd Test&lt;/pre&gt;&#xD;
&#xD;
&lt;pre&gt;$ git init&lt;/pre&gt;&#xD;
&#xD;
&lt;pre&gt;git初始化&lt;/pre&gt;&#xD;
&#xD;
&lt;pre&gt;$ touch README&lt;/pre&gt;&#xD;
&#xD;
&lt;pre&gt;$ git add README&lt;/pre&gt;&#xD;
&#xD;
&lt;pre&gt;增加README文件&lt;/pre&gt;&#xD;
&#xD;
&lt;pre&gt;$ git commit README&lt;/pre&gt;&#xD;
&#xD;
&lt;pre&gt;$ git commit -m 'first commit'&#xD;
$ git remote add origin &lt;a href="mailto:git@github.com:henllyee/Test.git"&gt;git@github.com:henllyee/Test.git&lt;/a&gt;&lt;/pre&gt;&#xD;
&#xD;
&lt;pre&gt;$ git push -u origin master&lt;/pre&gt;&#xD;
&#xD;
&lt;pre&gt;提交到github中&lt;/pre&gt;&#xD;
&#xD;
&lt;pre&gt;这个时候在Repository中就可以看到提交进去的README文件：&lt;/pre&gt;&#xD;
&#xD;
&lt;pre&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Henllyee/201202/201202022038229427.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Henllyee/201202/20120202203823540.png" width="709" height="112" /&gt;&lt;/a&gt;&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;总结&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;本篇post主要是初步认识下git/github,后面详细学习下git的常用命令。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/Henllyee/aggbug/2336185.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Henllyee/archive/2012/02/02/Git_Firt.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/Henllyee/archive/2011/09/12/Specification.html</id><title type="text">DDD中的Specification模式</title><summary type="text">在领域驱动开发中，我们会常用到Repository、Unit of Work等模式，而Specification模式并不是很常用，Specification模式在领域层中主要为我们实现领域规则的自由组合。 关于Specification 首先我们来看常见的Specification模式中的类图（来自于http://en.wikipedia.org/wiki/Specification_pattern）： Specification，规格说明书，这里我们可以理解为规则约束，我们可以对每个规则定义一个Specification，同时也可以将不同的Specification进行组合使用。 ...</summary><published>2011-09-12T08:44:00Z</published><updated>2011-09-12T08:44:00Z</updated><author><name>Henry Cui</name><uri>http://www.cnblogs.com/Henllyee/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Henllyee/archive/2011/09/12/Specification.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Henllyee/archive/2011/09/12/Specification.html"/><content type="html">&lt;p&gt;在领域驱动开发中，我们会常用到Repository、Unit of Work等模式，而Specification模式并不是很常用，Specification模式在领域层中主要为我们实现领域规则的自由组合。&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;关于Specification&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;首先我们来看常见的Specification模式中的类图（来自于&lt;a title="http://en.wikipedia.org/wiki/Specification_pattern" href="http://en.wikipedia.org/wiki/Specification_pattern"&gt;http://en.wikipedia.org/wiki/Specification_pattern&lt;/a&gt;）：&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Henllyee/201109/201109121643222984.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Specification_UML" border="0" alt="Specification_UML" src="http://images.cnblogs.com/cnblogs_com/Henllyee/201109/201109121643232211.png" width="545" height="327" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Specification，规格说明书，这里我们可以理解为规则约束，我们可以对每个规则定义一个Specification，同时也可以将不同的Specification进行组合使用。&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;简单实现&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;首先我们定义ISpecification接口：&lt;/p&gt;  &lt;pre &gt;&lt;span style="color: blue"&gt;public interface &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt;&#xD;
{&#xD;
    &lt;span style="color: blue"&gt;bool &lt;/span&gt;IsSatisfiedBy(T candidate);&#xD;
}&#xD;
&lt;font face="Georgia"&gt;&lt;/font&gt;&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;我们定义ICompsiteSpecification，这里使用了Compsite模式（组合模式）&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;&lt;span style="color: blue"&gt;public interface &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ICompsiteSpecification&lt;/span&gt;&amp;lt;T&amp;gt;:&lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt;&#xD;
{&#xD;
    &lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt; Add(&lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt; other);&#xD;
&#xD;
    &lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt; Or(&lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt; other);&#xD;
&#xD;
    &lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt; Not();&#xD;
}&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;AddSpecification:&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;AddSpecification&lt;/span&gt;&amp;lt;T&amp;gt;:&lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt;&#xD;
{&#xD;
    &lt;span style="color: blue"&gt;private &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt; _Left;&#xD;
    &lt;span style="color: blue"&gt;private &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt; _Right;&#xD;
&#xD;
    &lt;span style="color: blue"&gt;public &lt;/span&gt;AddSpecification(&lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt; left,&lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt; right)&#xD;
    {&#xD;
        _Left = left;&#xD;
        _Right = right;&#xD;
    }&#xD;
&#xD;
    &lt;span style="color: blue"&gt;public bool &lt;/span&gt;IsSatisfiedBy(T candidate)&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;return &lt;/span&gt;_Left.IsSatisfiedBy(candidate) &amp;amp;&amp;amp; _Right.IsSatisfiedBy(candidate);&#xD;
    }&#xD;
}&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;OrSpecification:&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;OrSpecification&lt;/span&gt;&amp;lt;T&amp;gt;:&lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt;&#xD;
{&#xD;
    &lt;span style="color: blue"&gt;private &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt; _Left;&#xD;
    &lt;span style="color: blue"&gt;private &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt; _Right;&#xD;
&#xD;
    &lt;span style="color: blue"&gt;public &lt;/span&gt;OrSpecification(&lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt; left, &lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt; right)&#xD;
    {&#xD;
        _Left = left;&#xD;
        _Right = right;&#xD;
    }&#xD;
&#xD;
    &lt;span style="color: blue"&gt;public bool &lt;/span&gt;IsSatisfiedBy(T candidate)&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;return &lt;/span&gt;_Left.IsSatisfiedBy(candidate) || _Right.IsSatisfiedBy(candidate);&#xD;
    }&#xD;
}&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;NoSpecification:&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;NotSpecification&lt;/span&gt;&amp;lt;T&amp;gt;:&lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt;&#xD;
{&#xD;
    &lt;span style="color: blue"&gt;private &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt; _Wrapped;&#xD;
&#xD;
    &lt;span style="color: blue"&gt;public &lt;/span&gt;NotSpecification(&lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt; wrapped)&#xD;
    {&#xD;
        _Wrapped = wrapped;&#xD;
    }&#xD;
&#xD;
    &lt;span style="color: blue"&gt;public bool &lt;/span&gt;IsSatisfiedBy(T candidate)&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;return &lt;/span&gt;(!_Wrapped.IsSatisfiedBy(candidate));&#xD;
    }&#xD;
}&#xD;
&lt;font face="Georgia"&gt;&lt;/font&gt;&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;CompositeSpecification:&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;&lt;span style="color: blue"&gt;public abstract class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;CompositeSpecification&lt;/span&gt;&amp;lt;T&amp;gt;:&lt;span style="color: #2b91af"&gt;ICompsiteSpecification&lt;/span&gt;&amp;lt;T&amp;gt;&#xD;
{&#xD;
&#xD;
    &lt;span style="color: blue"&gt;public abstract bool &lt;/span&gt;IsSatisfiedBy(T candidate);&#xD;
&#xD;
    &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt; Add(&lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt; other)&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;return new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;AddSpecification&lt;/span&gt;&amp;lt;T&amp;gt;(&lt;span style="color: blue"&gt;this&lt;/span&gt;, other);&#xD;
    }&#xD;
&#xD;
    &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt; Or(&lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt; other)&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;return new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;OrSpecification&lt;/span&gt;&amp;lt;T&amp;gt;(&lt;span style="color: blue"&gt;this&lt;/span&gt;, other);&#xD;
    }&#xD;
&#xD;
    &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt; Not()&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;return new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;NotSpecification&lt;/span&gt;&amp;lt;T&amp;gt;(&lt;span style="color: blue"&gt;this&lt;/span&gt;);&#xD;
    }&#xD;
}&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;我们举了个实际的例子进行使用，比如我们要获取一个数组里面所有的大于0而且是偶数的数字。这个时候我们可以定义两个Specification，一个是整数的Specification，一个是偶数的Specification：&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;EvenSpecification&lt;/span&gt;:&lt;span style="color: #2b91af"&gt;CompositeSpecification&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;&amp;gt;&#xD;
{&#xD;
    &lt;span style="color: blue"&gt;public override bool &lt;/span&gt;IsSatisfiedBy(&lt;span style="color: blue"&gt;int &lt;/span&gt;candidate)&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;return &lt;/span&gt;candidate % 2 == 0;&#xD;
    }&#xD;
}&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;我们再定义一个判断为正数的Specification:&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PositiveSpecification&lt;/span&gt;:&lt;span style="color: #2b91af"&gt;CompositeSpecification&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;&amp;gt;&#xD;
{&#xD;
    &lt;span style="color: blue"&gt;public override bool &lt;/span&gt;IsSatisfiedBy(&lt;span style="color: blue"&gt;int &lt;/span&gt;candidate)&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;return &lt;/span&gt;candidate &amp;gt; 0;&#xD;
    }&#xD;
}&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;使用:&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;&lt;span style="color: blue"&gt;static void &lt;/span&gt;Main(&lt;span style="color: blue"&gt;string&lt;/span&gt;[] args)&#xD;
{&#xD;
    &lt;span style="color: blue"&gt;var &lt;/span&gt;numbers = &lt;span style="color: #2b91af"&gt;Enumerable&lt;/span&gt;.Range(-10,20);&#xD;
    &lt;span style="color: blue"&gt;var &lt;/span&gt;postivieSpecification = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PositiveSpecification&lt;/span&gt;();&#xD;
    &lt;span style="color: blue"&gt;var &lt;/span&gt;compositSpecification = postivieSpecification.Add(&lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;EvenSpecification&lt;/span&gt;());&#xD;
    &lt;span style="color: blue"&gt;foreach &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;item &lt;span style="color: blue"&gt;in &lt;/span&gt;numbers.Where(i =&amp;gt; compositSpecification.IsSatisfiedBy(i)))&#xD;
    {&#xD;
        &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(item);&#xD;
    }&#xD;
    &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.ReadKey();&#xD;
}&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;DDD中使用&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;举个在我们实际业务中的查询来说明下吧。在.net 3.0之后我们有了Lambda表达式，我们可以通过更为优雅的一种方式来实现了:&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;&lt;span style="color: blue"&gt;public interface &lt;/span&gt;ISpecification&amp;lt;T&amp;gt;&#xD;
{&#xD;
    &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;&amp;lt;Func&amp;lt;T, &lt;span style="color: blue"&gt;bool&lt;/span&gt;&amp;gt;&amp;gt; IsSatisfiedBy();&#xD;
}&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;在这里IsSatisfiedBy方法返回的不是bool类型的，而是返回一个Lambda表达式，是为了跟Where进行配合使用。&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;这个时候我们对Expression&amp;lt;Func&amp;lt;T,bool&amp;gt;&amp;gt;类型进行扩展增加其And、Or方法：&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;&lt;span style="color: blue"&gt;public static class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ExpressionBuilder&#xD;
&lt;/span&gt;{&#xD;
    &lt;span style="color: blue"&gt;public static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;&amp;lt;T&amp;gt; Compose&amp;lt;T&amp;gt;(&lt;span style="color: blue"&gt;this &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;&amp;lt;T&amp;gt; left,&lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;&amp;lt;T&amp;gt; right,&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;&amp;gt; merge)&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;var &lt;/span&gt;params1 = left.Parameters;&#xD;
        &lt;span style="color: blue"&gt;var &lt;/span&gt;params2 = right.Parameters;&#xD;
        &lt;span style="color: blue"&gt;var &lt;/span&gt;map = params1.Select((p,i)=&amp;gt; &lt;span style="color: blue"&gt;new &lt;/span&gt;{p,s= params2[i]}).ToDictionary(p=&amp;gt;p.s,p=&amp;gt;p.p);&#xD;
        &lt;span style="color: blue"&gt;var &lt;/span&gt;rightBody = &lt;span style="color: #2b91af"&gt;ParameterRebinder&lt;/span&gt;.ReplaceParameters(map,right.Body);&#xD;
        &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.Lambda&amp;lt;T&amp;gt;(merge(left, rightBody), left.Parameters);&#xD;
    }&#xD;
&#xD;
    &lt;span style="color: blue"&gt;public static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;T,&lt;span style="color: blue"&gt;bool&lt;/span&gt;&amp;gt;&amp;gt; And&amp;lt;T&amp;gt;(&lt;span style="color: blue"&gt;this &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;T,&lt;span style="color: blue"&gt;bool&lt;/span&gt;&amp;gt;&amp;gt; left,&lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;T,&lt;span style="color: blue"&gt;bool&lt;/span&gt;&amp;gt;&amp;gt; right)&#xD;
    {&#xD;
       &lt;span style="color: blue"&gt;return &lt;/span&gt;left.Compose(right, &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.Add);&#xD;
    }&#xD;
&#xD;
    &lt;span style="color: blue"&gt;public static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;T, &lt;span style="color: blue"&gt;bool&lt;/span&gt;&amp;gt;&amp;gt; Or&amp;lt;T&amp;gt;(&lt;span style="color: blue"&gt;this &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;T, &lt;span style="color: blue"&gt;bool&lt;/span&gt;&amp;gt;&amp;gt; left, &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;T, &lt;span style="color: blue"&gt;bool&lt;/span&gt;&amp;gt;&amp;gt; right)&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;return &lt;/span&gt;left.Compose(right, &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.Or);&#xD;
    }&#xD;
}&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;Visitor:&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ParameterRebinder&lt;/span&gt;:&lt;span style="color: #2b91af"&gt;ExpressionVisitor&#xD;
&lt;/span&gt;{&#xD;
    &lt;span style="color: blue"&gt;private readonly &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;ParameterExpression&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;ParameterExpression&lt;/span&gt;&amp;gt; _Map;&#xD;
&#xD;
    &lt;span style="color: blue"&gt;public &lt;/span&gt;ParameterRebinder(&lt;span style="color: #2b91af"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;ParameterExpression&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;ParameterExpression&lt;/span&gt;&amp;gt; map)&#xD;
    {&#xD;
        _Map = map;&#xD;
    }&#xD;
&#xD;
    &lt;span style="color: blue"&gt;protected override &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Expression &lt;/span&gt;VisitParameter(&lt;span style="color: #2b91af"&gt;ParameterExpression &lt;/span&gt;node)&#xD;
    {&#xD;
        &lt;span style="color: #2b91af"&gt;ParameterExpression &lt;/span&gt;replacement;&#xD;
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(_Map.TryGetValue(node,&lt;span style="color: blue"&gt;out &lt;/span&gt;replacement))&#xD;
        {&#xD;
            node = replacement;&#xD;
        }&#xD;
        &lt;span style="color: blue"&gt;return base&lt;/span&gt;.VisitParameter(node);&#xD;
    }&#xD;
&#xD;
    &lt;span style="color: blue"&gt;public static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Expression &lt;/span&gt;ReplaceParameters(&lt;span style="color: #2b91af"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;ParameterExpression&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;ParameterExpression&lt;/span&gt;&amp;gt; map, &lt;span style="color: #2b91af"&gt;Expression &lt;/span&gt;exp)&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;return &lt;/span&gt;(&lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ParameterRebinder&lt;/span&gt;(map)).Visit(exp);&#xD;
    }&#xD;
}&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;上面的扩展为了我们方便的实现Expression&amp;lt;Func&amp;lt;T,bool&amp;gt;&amp;gt;类型进行我们逻辑And、Or操作。对于表达式书不太熟悉的同学可以参考MSDN上面的两篇文章：&lt;a title="http://msdn.microsoft.com/zh-cn/library/bb397951.aspx" href="http://msdn.microsoft.com/zh-cn/library/bb397951.aspx"&gt;http://msdn.microsoft.com/zh-cn/library/bb397951.aspx&lt;/a&gt;、&lt;a title="http://msdn.microsoft.com/zh-cn/library/bb546136.aspx" href="http://msdn.microsoft.com/zh-cn/library/bb546136.aspx"&gt;http://msdn.microsoft.com/zh-cn/library/bb546136.aspx&lt;/a&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;为了方便我们进行And、Or动作，我们可以对操作符进行重载：&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;&lt;span style="color: blue"&gt;public abstract  class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Specification&lt;/span&gt;&amp;lt;T&amp;gt;:&lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt;&#xD;
{&#xD;
&#xD;
    &lt;span style="color: blue"&gt;public abstract &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;T, &lt;span style="color: blue"&gt;bool&lt;/span&gt;&amp;gt;&amp;gt; IsSatisfiedBy();&#xD;
&#xD;
    &lt;span style="color: blue"&gt;public static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt; &lt;span style="color: blue"&gt;operator &lt;/span&gt;|(&lt;span style="color: #2b91af"&gt;Specification&lt;/span&gt;&amp;lt;T&amp;gt; left, &lt;span style="color: #2b91af"&gt;Specification&lt;/span&gt;&amp;lt;T&amp;gt; right)&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;return new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;OrSpecification&lt;/span&gt;&amp;lt;T&amp;gt;(left, right);&#xD;
    }&#xD;
&#xD;
    &lt;span style="color: blue"&gt;public static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt; &lt;span style="color: blue"&gt;operator &lt;/span&gt;&amp;amp;(&lt;span style="color: #2b91af"&gt;Specification&lt;/span&gt;&amp;lt;T&amp;gt; left, &lt;span style="color: #2b91af"&gt;Specification&lt;/span&gt;&amp;lt;T&amp;gt; right)&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;return new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;AddSpecification&lt;/span&gt;&amp;lt;T&amp;gt;(left, right);&#xD;
    }&#xD;
&#xD;
    &lt;span style="color: blue"&gt;public static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt; &lt;span style="color: blue"&gt;operator &lt;/span&gt;!(&lt;span style="color: #2b91af"&gt;Specification&lt;/span&gt;&amp;lt;T&amp;gt; specification)&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;return new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;NotSpecification&lt;/span&gt;&amp;lt;T&amp;gt;(specification);&#xD;
    }&#xD;
&#xD;
    &lt;span style="color: blue"&gt;public static bool operator false&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Specification&lt;/span&gt;&amp;lt;T&amp;gt; specification)&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;return false&lt;/span&gt;;&#xD;
    }&#xD;
&#xD;
    &lt;span style="color: blue"&gt;public static bool operator true&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Specification&lt;/span&gt;&amp;lt;T&amp;gt; specification)&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;return true&lt;/span&gt;;&#xD;
    }&#xD;
}&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;CompositeSpecification:&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;&lt;span style="color: blue"&gt;public abstract class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;CompositeSpecification&lt;/span&gt;&amp;lt;T&amp;gt;:&lt;span style="color: #2b91af"&gt;Specification&lt;/span&gt;&amp;lt;T&amp;gt;&#xD;
{&#xD;
    &lt;span style="color: blue"&gt;public abstract &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt; Left { &lt;span style="color: blue"&gt;get&lt;/span&gt;; }&#xD;
&#xD;
    &lt;span style="color: blue"&gt;public abstract &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt; Right { &lt;span style="color: blue"&gt;get&lt;/span&gt;; }&#xD;
    &#xD;
}&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;And:&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;AddSpecification&lt;/span&gt;&amp;lt;T&amp;gt;:&lt;span style="color: #2b91af"&gt;CompositeSpecification&lt;/span&gt;&amp;lt;T&amp;gt;&#xD;
{&#xD;
    &lt;span style="color: blue"&gt;private &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt; _Left;&#xD;
    &lt;span style="color: blue"&gt;private &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt; _Right;&#xD;
&#xD;
    &lt;span style="color: blue"&gt;public &lt;/span&gt;AddSpecification(&lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt; left,&lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt; right)&#xD;
    {&#xD;
        _Left = left;&#xD;
        _Right = right;&#xD;
    }&#xD;
&#xD;
    &lt;span style="color: blue"&gt;public override &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt; Left&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;get &lt;/span&gt;{ &lt;span style="color: blue"&gt;return &lt;/span&gt;_Left; }&#xD;
    }&#xD;
&#xD;
    &lt;span style="color: blue"&gt;public override &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt; Right&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;get &lt;/span&gt;{ &lt;span style="color: blue"&gt;return &lt;/span&gt;_Right; }&#xD;
    }&#xD;
&#xD;
&#xD;
&#xD;
    &lt;span style="color: blue"&gt;public override &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;T,&lt;span style="color: blue"&gt;bool&lt;/span&gt;&amp;gt;&amp;gt; IsSatisfiedBy()&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;return &lt;/span&gt;_Left.IsSatisfiedBy().And(_Right.IsSatisfiedBy());&#xD;
    }&#xD;
}&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;Or:&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;OrSpecification&lt;/span&gt;&amp;lt;T&amp;gt; : &lt;span style="color: #2b91af"&gt;CompositeSpecification&lt;/span&gt;&amp;lt;T&amp;gt;&#xD;
{&#xD;
    &lt;span style="color: blue"&gt;private &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt; _Left;&#xD;
    &lt;span style="color: blue"&gt;private &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt; _Right;&#xD;
&#xD;
    &lt;span style="color: blue"&gt;public &lt;/span&gt;OrSpecification(&lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt; left, &lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt; right)&#xD;
    {&#xD;
        _Left = left;&#xD;
        _Right = right;&#xD;
    }&#xD;
&#xD;
    &lt;span style="color: blue"&gt;public override &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt; Left&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;get &lt;/span&gt;{ &lt;span style="color: blue"&gt;return &lt;/span&gt;_Left; }&#xD;
    }&#xD;
&#xD;
    &lt;span style="color: blue"&gt;public override &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt; Right&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;get &lt;/span&gt;{ &lt;span style="color: blue"&gt;return &lt;/span&gt;_Right; }&#xD;
    }&#xD;
&#xD;
&#xD;
    &lt;span style="color: blue"&gt;public override &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;T, &lt;span style="color: blue"&gt;bool&lt;/span&gt;&amp;gt;&amp;gt; IsSatisfiedBy()&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;return &lt;/span&gt;_Left.IsSatisfiedBy().Or(_Right.IsSatisfiedBy());&#xD;
    }&#xD;
&#xD;
}&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;Not:&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;NotSpecification&lt;/span&gt;&amp;lt;T&amp;gt;:&lt;span style="color: #2b91af"&gt;Specification&lt;/span&gt;&amp;lt;T&amp;gt;&#xD;
{&#xD;
    &lt;span style="color: blue"&gt;private &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt; _Wrapped;&#xD;
&#xD;
    &lt;span style="color: blue"&gt;public &lt;/span&gt;NotSpecification(&lt;span style="color: #2b91af"&gt;ISpecification&lt;/span&gt;&amp;lt;T&amp;gt; wrapped)&#xD;
    {&#xD;
        _Wrapped = wrapped;&#xD;
    }&#xD;
&#xD;
    &lt;span style="color: blue"&gt;public override &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;T,&lt;span style="color: blue"&gt;bool&lt;/span&gt;&amp;gt;&amp;gt; IsSatisfiedBy()&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.Lambda&amp;lt;&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;T, &lt;span style="color: blue"&gt;bool&lt;/span&gt;&amp;gt;&amp;gt;(&lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.Not(_Wrapped.IsSatisfiedBy().Body),&#xD;
                                                     _Wrapped.IsSatisfiedBy().Parameters.Single());&#xD;
    }&#xD;
}&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;其实我们上面的实现的类图是这样的一种结构：&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Henllyee/201109/201109121643249802.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Henllyee/201109/201109121643313659.png" width="641" height="411" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;举个例子，比如我们在实际的查询中，可以定义自己的Specification，同时可以通过And、Or进行查询规则的组合，然后传递给Repository.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;总结&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;本文中主要讲解了Specification模式，以及我们在项目中如何使用Specification的。希望对您有用。&lt;/p&gt;&#xD;
&#xD;
&lt;div style="border-bottom: #cac8ca 1px dotted; border-left: #cac8ca 1px dotted; width: 100%; height: 70px; border-top: #cac8ca 1px dotted; border-right: #cac8ca 1px dotted"&gt;&#xD;
  &lt;div style="float: left"&gt;&lt;img alt="" src="http://images.cnblogs.com/cnblogs_com/henllyee/png-1665.png" /&gt; &lt;/div&gt;&#xD;
&#xD;
  &lt;div style="margin-top: 2px; float: left; margin-left: 20px; font-size: 12px"&gt;&lt;span style="line-height: 20px; height: 20px"&gt;作者：Henllyee Cui&lt;/span&gt; &#xD;
&#xD;
    &lt;br /&gt;&lt;span style="line-height: 20px; height: 20px"&gt;出处： &lt;a style="color: #ff0000; text-decoration: none" href="http://henllyee.cnblogs.com/"&gt;http://henllyee.cnblogs.com/&lt;/a&gt; &lt;/span&gt;&#xD;
&#xD;
    &lt;br /&gt;&lt;span style="line-height: 20px; height: 20px"&gt;本文版权归作者和博客园共有，欢迎转载，但未经作者同意必须保留此段声明。 &lt;/span&gt;&lt;/div&gt;&#xD;
&lt;/div&gt;&lt;img src="http://www.cnblogs.com/Henllyee/aggbug/2174123.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Henllyee/archive/2011/09/12/Specification.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/Henllyee/archive/2011/08/07/Silverlight4-trip-Third.html</id><title type="text">Silverlight 4之旅（三）数据绑定（中）</title><summary type="text">在上篇文章中我们已经看过了绑定的基础知识，以及绑定数据源的选择问题。在本篇文章中我们看下绑定时Target的现实的问题。 自定义显示 很多时候我们的DataSource存储的数据并不可以直接用来显示，比如说我们对于Bool类型，需要显示为“是”或则“否”而不是“True”,“False”，甚至有的时候我们需要将DataSource的某个属性在多个不同的UI的地方进行不同的显示。 在我们进行绑定的时候，绑定机制默认选择类型的ToString方法进行绑定到UI上面，还好，在Silverlight中提供了Formatting的机制让我们来自定义我们的显示。我们可以通过Formatting来定义格式化</summary><published>2011-08-07T09:07:00Z</published><updated>2011-08-07T09:07:00Z</updated><author><name>Henry Cui</name><uri>http://www.cnblogs.com/Henllyee/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Henllyee/archive/2011/08/07/Silverlight4-trip-Third.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Henllyee/archive/2011/08/07/Silverlight4-trip-Third.html"/><content type="html">&lt;p&gt;在上篇文章中我们已经看过了绑定的基础知识，以及绑定数据源的选择问题。在本篇文章中我们看下绑定时Target的现实的问题。&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;自定义显示&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;很多时候我们的DataSource存储的数据并不可以直接用来显示，比如说我们对于Bool类型，需要显示为“是”或则“否”而不是“True”,“False”，甚至有的时候我们需要将DataSource的某个属性在多个不同的UI的地方进行不同的显示。&lt;/p&gt;  &lt;p&gt;在我们进行绑定的时候，绑定机制默认选择类型的ToString方法进行绑定到UI上面，还好，在Silverlight中提供了Formatting的机制让我们来自定义我们的显示。我们可以通过Formatting来定义格式化我们的显示，同时我们也可以通过Convert来进行转换，下面我们来看看Formatting部分。&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Formatting&amp;amp;Converter&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;在我们编写的代码中，我们可以通过String.Format方法进行一个值的格式化，在绑定时我们也可以使用,其语法类似于String.Format。比如我们我们希望将一个Decimal类型的显示为￥2011，我们可以通过这种方式：&lt;/p&gt;  &lt;pre &gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;TextBlock &lt;/span&gt;&lt;span style="color: red"&gt;Text&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515"&gt;Binding &lt;/span&gt;&lt;span style="color: red"&gt;Total&lt;/span&gt;&lt;span style="color: blue"&gt;,&lt;/span&gt;&lt;span style="color: red"&gt;StringFormat&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;\&lt;span style="color: blue"&gt;{&lt;/span&gt;0&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: #a31515"&gt;C&lt;/span&gt;\&lt;span style="color: blue"&gt;}}&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;TextBlock&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;&amp;#160;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;可是大部分时候,简单的Format对我们来说是不够用的，更多时候我们需要Convert来转换我们Source的值，比如说我们需要Bool值类型的显示为否\是.我们在定义一个Convert时必须需要继承于IValueConverter接口，在IValueConverter中有两个方法：Convert、ConvertBack。Convert方法是指将将Source数据绑定到Target时转换动作，而ConvertBack是指将Target的数据返回到Source时的转换。下面我们来定义一个BooleanConvert:&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;BooleanConvert &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;IValueConverter&#xD;
&lt;/span&gt;{&#xD;
&#xD;
    &lt;span style="color: blue"&gt;public object &lt;/span&gt;Convert(&lt;span style="color: blue"&gt;object &lt;/span&gt;value, &lt;span style="color: #2b91af"&gt;Type &lt;/span&gt;targetType, &lt;span style="color: blue"&gt;object &lt;/span&gt;parameter, System.Globalization.&lt;span style="color: #2b91af"&gt;CultureInfo &lt;/span&gt;culture)&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;var &lt;/span&gt;booleanValue = &lt;span style="color: #2b91af"&gt;Boolean&lt;/span&gt;.Parse(value.ToString());&#xD;
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(booleanValue) &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #a31515"&gt;&amp;quot;Yes&amp;quot;&lt;/span&gt;;&#xD;
        &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #a31515"&gt;&amp;quot;No&amp;quot;&lt;/span&gt;;&#xD;
    }&#xD;
&#xD;
    &lt;span style="color: blue"&gt;public object &lt;/span&gt;ConvertBack(&lt;span style="color: blue"&gt;object &lt;/span&gt;value, &lt;span style="color: #2b91af"&gt;Type &lt;/span&gt;targetType, &lt;span style="color: blue"&gt;object &lt;/span&gt;parameter, System.Globalization.&lt;span style="color: #2b91af"&gt;CultureInfo &lt;/span&gt;culture)&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;var &lt;/span&gt;strValue = value.ToString().ToLower();&#xD;
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(strValue.Equals(&lt;span style="color: #a31515"&gt;&amp;quot;yes&amp;quot;&lt;/span&gt;))&#xD;
            &lt;span style="color: blue"&gt;return true&lt;/span&gt;;&#xD;
        &lt;span style="color: blue"&gt;return false&lt;/span&gt;;&#xD;
    }&#xD;
}&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;我们看看如何使用，在原来的Person中增加了Married属性：&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;&lt;span style="color: blue"&gt;private bool &lt;/span&gt;_Married;&#xD;
&lt;span style="color: blue"&gt;public bool &lt;/span&gt;Married { &#xD;
    &lt;span style="color: blue"&gt;get &lt;/span&gt;{ &lt;span style="color: blue"&gt;return &lt;/span&gt;_Married; }&#xD;
    &lt;span style="color: blue"&gt;set &lt;/span&gt;{&#xD;
        _Married = &lt;span style="color: blue"&gt;value&lt;/span&gt;;&#xD;
        NotifyPropertyChanged(&lt;span style="color: #a31515"&gt;&amp;quot;Married&amp;quot;&lt;/span&gt;);&#xD;
    }&#xD;
}&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;然后我们再资源中增加BooleanConver的引用：&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;UserControl.Resources&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;local&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: #a31515"&gt;BooleanConvert &lt;/span&gt;&lt;span style="color: red"&gt;x&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;Key&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;BooleanConvert&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;local&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: #a31515"&gt;BooleanConvert&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;UserControl.Resources&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;在ListBox中增加Married:&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;TextBlock &lt;/span&gt;&lt;span style="color: red"&gt;Text&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Married:&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;FontSize&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;12&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Margin&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;3,3,0,0&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Grid.Column&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;2&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;TextBlock&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;TextBlock &lt;/span&gt;&lt;span style="color: red"&gt;Text&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515"&gt;Binding &lt;/span&gt;&lt;span style="color: red"&gt;Married&lt;/span&gt;&lt;span style="color: blue"&gt;,&lt;/span&gt;&lt;span style="color: red"&gt;Converter&lt;/span&gt;&lt;span style="color: blue"&gt;={&lt;/span&gt;&lt;span style="color: #a31515"&gt;StaticResource &lt;/span&gt;&lt;span style="color: red"&gt;BooleanConvert&lt;/span&gt;&lt;span style="color: blue"&gt;}}&amp;quot;&#xD;
            &lt;/span&gt;&lt;span style="color: red"&gt;FontSize&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;12&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Margin&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;0,3,0,0&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Grid.Column&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;3&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;TextBlock&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;运行效果：&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Henllyee/201108/201108071706515869.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Henllyee/201108/201108071706525736.png" width="244" height="237" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;在有的时候我们会出现转换错误，这个时候我们需要提供默认的fallback Value，下面我们看下两个中特殊情况下的处理。&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;fallback values &amp;amp; null values&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;在绑定时候，总会出现错误的情况，比如在一个属性的Geter中发生错误了等等，这个时候我们在绑定的表达式中指定下FallbackValue是非常有用的，我们可以这样指定：&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;TextBlock &lt;/span&gt;&lt;span style="color: red"&gt;Text&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515"&gt;Binding &lt;/span&gt;&lt;span style="color: red"&gt;Married&lt;/span&gt;&lt;span style="color: blue"&gt;,&lt;/span&gt;&lt;span style="color: red"&gt;Converter&lt;/span&gt;&lt;span style="color: blue"&gt;={&lt;/span&gt;&lt;span style="color: #a31515"&gt;StaticResource &lt;/span&gt;&lt;span style="color: red"&gt;BooleanConvert&lt;/span&gt;&lt;span style="color: blue"&gt;},&lt;/span&gt;&lt;span style="color: red"&gt;FallbackValue&lt;/span&gt;&lt;span style="color: blue"&gt;=Error}&amp;quot;&#xD;
            &lt;/span&gt;&lt;span style="color: red"&gt;FontSize&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;12&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Margin&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;0,3,0,0&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Grid.Column&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;3&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;TextBlock&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;&amp;#160;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;有的时候我们的源数据中是Null值的时候，我们也需要额外的进行显示，在表达式中，我们可以通过指定TargetNullValue：&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;TextBlock &lt;/span&gt;&lt;span style="color: red"&gt;Text&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515"&gt;Binding &lt;/span&gt;&lt;span style="color: red"&gt;Married&lt;/span&gt;&lt;span style="color: blue"&gt;,&lt;/span&gt;&lt;span style="color: red"&gt;Converter&lt;/span&gt;&lt;span style="color: blue"&gt;={&lt;/span&gt;&lt;span style="color: #a31515"&gt;StaticResource &lt;/span&gt;&lt;span style="color: red"&gt;BooleanConvert&lt;/span&gt;&lt;span style="color: blue"&gt;},&lt;/span&gt;&lt;span style="color: red"&gt;FallbackValue&lt;/span&gt;&lt;span style="color: blue"&gt;=Error,&lt;/span&gt;&lt;span style="color: red"&gt;TargetNullValue&lt;/span&gt;&lt;span style="color: blue"&gt;=Miss}&amp;quot;&#xD;
            &lt;/span&gt;&lt;span style="color: red"&gt;FontSize&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;12&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Margin&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;0,3,0,0&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Grid.Column&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;3&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;TextBlock&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;&amp;#160;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;总结&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;本篇文章中我们主要看过了数据绑定时的自定义显示方面的内容，下篇文章中会就数据模板进行了解。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/Henllyee/aggbug/2130127.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Henllyee/archive/2011/08/07/Silverlight4-trip-Third.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/Henllyee/archive/2011/07/20/Silverlight4-trip-Second.html</id><title type="text">Silverlight 4之旅（二）数据绑定（上）</title><summary type="text">在上篇Post中通过一个简单的Demo，跟Silverlight有了一次接触，本篇文章中会就Silverlight 4中的绑定进行些说明。绑定可以说是Silverlight跟WPF中最为重要的技术，绑定的作用就是让我们的数据源跟SilverlightUI现实进行动态绑定。 绑定的基础概念 绑定是一种比较有效的建立UI跟Data之间的链接，在Silverlight中我们可以将UI的控件中的某个属性进行绑定，也可以将UI的几个属性之间进行相互绑定。绑定中有三个核心的概念：Source(数据源)、Binding Model（绑定模式）、Traget（目标UI）。这张图可以很好说明这三者之间的关系： </summary><published>2011-07-20T12:39:00Z</published><updated>2011-07-20T12:39:00Z</updated><author><name>Henry Cui</name><uri>http://www.cnblogs.com/Henllyee/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Henllyee/archive/2011/07/20/Silverlight4-trip-Second.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Henllyee/archive/2011/07/20/Silverlight4-trip-Second.html"/><content type="html">&lt;p&gt;在上篇Post中通过一个简单的Demo，跟Silverlight有了一次接触，本篇文章中会就Silverlight 4中的绑定进行些说明。绑定可以说是Silverlight跟WPF中最为重要的技术，绑定的作用就是让我们的数据源跟SilverlightUI现实进行动态绑定。&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;绑定的基础概念&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;绑定是一种比较有效的建立UI跟Data之间的链接，在Silverlight中我们可以将UI的控件中的某个属性进行绑定，也可以将UI的几个属性之间进行相互绑定。绑定中有三个核心的概念：Source(数据源)、Binding Model（绑定模式）、Traget（目标UI）。这张图可以很好说明这三者之间的关系：&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Henllyee/201107/201107202038591858.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Henllyee/201107/201107202039009840.png" width="488" height="100" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;绑定的数据源一般是我们的CLR Object；Binding Mode是指我们使用绑定是所选择绑定的模式，共三种类型；目标我们的UI。我们先说说绑定的基本的语法。&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;语法基础&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;其实绑定的核心是通过Binding类建立Source跟Target之间的链接的，我们可以通过运行时指定，也可以通过在设计时进行指定。我们先看看运行时指定的语法：&lt;/p&gt;  &lt;p&gt;首先我们在xaml中拥有如下控件：&lt;/p&gt;  &lt;pre &gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;TextBox &lt;/span&gt;&lt;span style="color: red"&gt;x&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;Name&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;dateTextBox&amp;quot; /&amp;gt;&#xD;
&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;我们在后台代码中指定其绑定到当前时间:&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;dateNow = &lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt;.Now;&#xD;
&lt;span style="color: blue"&gt;var &lt;/span&gt;binding = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Binding&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;dateNow&amp;quot;&lt;/span&gt;);&#xD;
binding.Source = dateNow;&#xD;
binding.Mode = &lt;span style="color: #2b91af"&gt;BindingMode&lt;/span&gt;.OneWay;&#xD;
dateTextBox.SetBinding(&lt;span style="color: #2b91af"&gt;TextBox&lt;/span&gt;.TextProperty, binding);&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;上面的代码的中,首先我们构建了Bingding对象，然后设置其Source以及BingdingMode，然后dateTextBox将其绑定设置到其TextProperty上面。这里面的Source即dateNow,BingMode选择的是OnWay的方式，Target即dateTextBox，正是上面说说的绑定的三个核心的概念。&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;下面我们看下如何在设计时指定：&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;TextBox &lt;/span&gt;&lt;span style="color: red"&gt;x&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;Name&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;dateTextBox&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Text&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515"&gt;Binding &lt;/span&gt;&lt;span style="color: red"&gt;TimeOfDay&lt;/span&gt;&lt;span style="color: blue"&gt;,&lt;/span&gt;&lt;span style="color: red"&gt;Mode&lt;/span&gt;&lt;span style="color: blue"&gt;=OneWay}&amp;quot; /&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;在后台中我们指定了dateTextBox的DataContext属性：&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;dateNow = &lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt;.Now;&#xD;
dateTextBox.DataContext = dateNow;&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;其实上面的{}方式只是一种简洁的方式，其实上面的绑定语法可以如此表达：&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;TextBox &lt;/span&gt;&lt;span style="color: red"&gt;x&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;Name&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;dateTextBox&amp;quot;&amp;gt;&#xD;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;TextBox.Text&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Binding &lt;/span&gt;&lt;span style="color: red"&gt;Path&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;TimeOfDay&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Mode&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;OneWay&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Binding&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;TextBox.Text&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;TextBox&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;绑定Mode&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;绑定类型一共分为三种:1.OneTime;2.OneWay;TowWay.这三种模式在Source到Target绑定时，决定三种不同的绑定的类型。&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;1) OneTime&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;当我们使用OneTime绑定模式的时候，当Source发生改变的时候不会通知Target，只有在Source初始化时才会将其绑定到Target上面。&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;2) OneWay&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;OneWay是绑定Mode的默认值，在这种绑定的模式下，当Source发生改变的时候会通知并响应到Target上，如果Source的属性发生改变的时候，Target上面的属性就会自动改变。当时Target发生改变的时候，不会通知Source.&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;3) TwoWay&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;TowWay模式是指Target跟Source之间的改变会相互影响，我们在一些表单详细时会经常用到。&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;绑定Source&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;在绑定的源中,可以是一个CLR类型的Object，也可以是其他UI的某些属性上面，同事也可以绑定到自己本身的属性上面。下面我们来看下各种类型的绑定数据源的使用。&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;1）绑定到属性上面&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;在之前的例子里面我们看到了，将datetime的TimeOfDay绑定到了textblok上面，同时也是使用的OneWay的方式，即TimeOfDay发生改变，会更新到textblok上面，但是我们发现一个问题，就是现实的时候时间便没有自动更新。原因就是TimeOfDay属性没有做改变通知。我们回到第一篇文章中的&lt;a href="http://www.cnblogs.com/Henllyee/archive/2011/07/17/Silverlight4-trip-first.html"&gt;Person&lt;/a&gt;类型，在这里面我们如何实现属性通知呢：&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Person&lt;/span&gt;:&lt;span style="color: #2b91af"&gt;INotifyPropertyChanged&#xD;
&lt;/span&gt;{&#xD;
    &lt;span style="color: blue"&gt;public event &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PropertyChangedEventHandler &lt;/span&gt;PropertyChanged;&#xD;
&#xD;
    &lt;span style="color: blue"&gt;private string &lt;/span&gt;_Name;&#xD;
    &lt;span style="color: blue"&gt;public string &lt;/span&gt;Name&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;get &lt;/span&gt;{ &lt;span style="color: blue"&gt;return &lt;/span&gt;_Name; }&#xD;
        &lt;span style="color: blue"&gt;set &lt;/span&gt;{&#xD;
            _Name = &lt;span style="color: blue"&gt;value&lt;/span&gt;;&#xD;
            NotifyPropertyChanged(&lt;span style="color: #a31515"&gt;&amp;quot;Name&amp;quot;&lt;/span&gt;);&#xD;
        }&#xD;
    }&#xD;
&#xD;
    &lt;span style="color: blue"&gt;private &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ImageSource &lt;/span&gt;_HeadImg;&#xD;
    &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ImageSource &lt;/span&gt;HeadImg&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;get &lt;/span&gt;{ &lt;span style="color: blue"&gt;return &lt;/span&gt;_HeadImg; }&#xD;
        &lt;span style="color: blue"&gt;set &lt;/span&gt;{ &#xD;
            _HeadImg = &lt;span style="color: blue"&gt;value&lt;/span&gt;;&#xD;
            NotifyPropertyChanged(&lt;span style="color: #a31515"&gt;&amp;quot;HeadImg&amp;quot;&lt;/span&gt;);&#xD;
        }&#xD;
    }&#xD;
&#xD;
    &lt;span style="color: blue"&gt;public void &lt;/span&gt;NotifyPropertyChanged(&lt;span style="color: blue"&gt;string &lt;/span&gt;propertyName)&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(PropertyChanged != &lt;span style="color: blue"&gt;null&lt;/span&gt;)&#xD;
        {&#xD;
            PropertyChanged(&lt;span style="color: blue"&gt;this&lt;/span&gt;,&#xD;
            &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PropertyChangedEventArgs&lt;/span&gt;(propertyName));&#xD;
        }&#xD;
    }&#xD;
}&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;我们继承了INotifyPropertyChanged,INotifyPropertyChanged的作用就是做属性改变的广播通知,INotifyPropertyChanged可以保证我们在使用OneWay或则TowWay的模式的时候UI Target跟Source Property保证同步的。但是INotifyPropertyChanged的同步是通过 PropertyChangedEventHandler委托去告诉的，所以我们在属性改变时去触发事件PropertyChanged。 &#xD;
  &lt;br /&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;2）绑定到对象&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;在上面的例子里面我们主要都是看到了将一个数据源中的属性绑定上去的，其实更多的时候我们会将整个Object作为数据源来进行绑定。这个时候我们可以将Object指定到DataContext属性上面，DataContext是一个DepencyProperty允许我们共享数据，关键的是，我们在一个控件上指定了DataContext之后，其子element也可以使用到这个数据源。&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;我们在后台代码中：&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;personList = GetPersons();&#xD;
&lt;span style="color: blue"&gt;this&lt;/span&gt;.DataContext = personList[0];&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;前台Xaml中：&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Image &lt;/span&gt;&lt;span style="color: red"&gt;Height&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;100&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Width&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;100&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Source&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515"&gt;Binding &lt;/span&gt;&lt;span style="color: red"&gt;HeadImg&lt;/span&gt;&lt;span style="color: blue"&gt;}&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Image&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;TextBlock &lt;/span&gt;&lt;span style="color: red"&gt;Text&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515"&gt;Binding &lt;/span&gt;&lt;span style="color: red"&gt;Name&lt;/span&gt;&lt;span style="color: blue"&gt;}&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;FontSize&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;14&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Margin&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;3&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;TextBlock&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;运行效果：&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Henllyee/201107/201107202039008379.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Henllyee/201107/201107202039018869.png" width="120" height="125" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;3）绑定到一个UIElement上面&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;SilverLight绑定源中也可以是UI控件的属性，我们来看下面的示例，一个新浪微博输入字符提示的示例，输入剩余字符个数的提醒：&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;StackPanel &lt;/span&gt;&lt;span style="color: red"&gt;Orientation&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Vertical&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Margin&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;50&amp;quot;&amp;gt;&#xD;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;TextBox &lt;/span&gt;&lt;span style="color: red"&gt;x&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;Name&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;weiboText&amp;quot;&#xD;
    &lt;/span&gt;&lt;span style="color: red"&gt;MaxLength&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;140&amp;quot;&#xD;
    &lt;/span&gt;&lt;span style="color: red"&gt;Text&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Hi Henry&amp;quot; /&amp;gt;&#xD;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;StackPanel &lt;/span&gt;&lt;span style="color: red"&gt;Orientation&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Horizontal&amp;quot;&amp;gt;&#xD;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;TextBlock &lt;/span&gt;&lt;span style="color: red"&gt;Text&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515"&gt;Binding &lt;/span&gt;&lt;span style="color: red"&gt;Text&lt;/span&gt;&lt;span style="color: blue"&gt;.Length, &lt;/span&gt;&lt;span style="color: red"&gt;ElementName&lt;/span&gt;&lt;span style="color: blue"&gt;=weiboText}&amp;quot; /&amp;gt;&#xD;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;TextBlock &lt;/span&gt;&lt;span style="color: red"&gt;Text&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;/&amp;quot; /&amp;gt;&#xD;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;TextBlock &lt;/span&gt;&lt;span style="color: red"&gt;Text&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515"&gt;Binding &lt;/span&gt;&lt;span style="color: red"&gt;MaxLength&lt;/span&gt;&lt;span style="color: blue"&gt;, &lt;/span&gt;&lt;span style="color: red"&gt;ElementName&lt;/span&gt;&lt;span style="color: blue"&gt;=weiboText}&amp;quot; /&amp;gt;&#xD;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;StackPanel&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;StackPanel&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;我们看到运行效果如下：&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Henllyee/201107/201107202039016676.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Henllyee/201107/201107202039019708.png" width="265" height="69" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;在上面的例子里面我们通过ElemetName属性去指定到某个控件上面。&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;4）绑定到集合类型上&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;其实在绑定到集合类型的数据源上面我们在上篇文章中见过了，主要需要指定其数据源到一个继承与ItemControl上的控件的ItemSource属性上。&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;总结&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;本篇文章中，主要介绍了绑定的基础知识、绑定的Mode的选择以及各种类型Source如何进行绑定。下篇文章中我们主要看下Target的显示问题。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/Henllyee/aggbug/2112076.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Henllyee/archive/2011/07/20/Silverlight4-trip-Second.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/Henllyee/archive/2011/07/17/Silverlight4-trip-first.html</id><title type="text">Silverlight 4之旅（一）</title><summary type="text">由于工作的关系，现在的项目要求表现层使用Silverlight来实现，本人也不得不走向Silverlight这条路了。也许只是匆匆过客，但是还是做个记录吧。 简介 Microsoft Silverlight 是一种跨浏览器、跨平台的 .NET Framework 实现，用于为 Web 生成和提供下一代媒体体验和丰富的交互式应用程序 (RIA)。Silverlight 统一了服务器、Web 和桌面的功能，统一了托管代码和动态语言、声明性编程和传统编程以及 Windows Presentation Foundation (WPF) 的功能。 Silverlight 允许您创建具有以下功能的最先进的</summary><published>2011-07-17T05:53:00Z</published><updated>2011-07-17T05:53:00Z</updated><author><name>Henry Cui</name><uri>http://www.cnblogs.com/Henllyee/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Henllyee/archive/2011/07/17/Silverlight4-trip-first.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Henllyee/archive/2011/07/17/Silverlight4-trip-first.html"/><content type="html">&lt;p&gt;由于工作的关系，现在的项目要求表现层使用Silverlight来实现，本人也不得不走向Silverlight这条路了。也许只是匆匆过客，但是还是做个记录吧。&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;简介&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Microsoft Silverlight 是一种跨浏览器、跨平台的 .NET Framework 实现，用于为 Web 生成和提供下一代媒体体验和丰富的交互式应用程序 (RIA)。Silverlight 统一了服务器、Web 和桌面的功能，统一了托管代码和动态语言、声明性编程和传统编程以及 Windows Presentation Foundation (WPF) 的功能。&lt;/p&gt;  &lt;p&gt;Silverlight 允许您创建具有以下功能的最先进的应用程序：&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;     &lt;p&gt;它是一种跨浏览器、跨平台的技术。它在所有常见的 Web 浏览器中运行，包括 Microsoft Internet Explorer、Mozilla Firefox 以及 Apple Safari 和谷歌浏览器，并在 Microsoft Windows 和 Apple Mac OS X 上运行。&lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;p&gt;它由可在数秒内安装的很小的下载程序支持。&lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;p&gt;它对视频和音频进行流处理。它将视频品质调整到适合各种环境：从移动设备到桌面浏览器以及 720p HDTV 视频模式。&lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;p&gt;它包括用户可以直接在浏览器中操作（拖动、旋转和缩放）的足够清晰的图形。&lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;p&gt;它读取数据并更新显示内容，但是不通过刷新整个页面来打断用户。&lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;p&gt;应用程序可以在 Web 浏览器中运行；您也可以配置应用程序，使用户可以在自己的计算机上运行该应用程序（浏览器外）。&lt;/p&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;第一个Demo&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;第一个例子一般都是从Hello World开始，这里我就不从Hello World开始了，我建立一个稍微有点实际意义的一个Demo来开始第一次之旅吧。Get Person——获取人员的信息。&lt;/p&gt;  &lt;p&gt;首先定义了Person：&lt;/p&gt;  &lt;pre &gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Person&#xD;
&lt;/span&gt;{&#xD;
    &lt;span style="color: blue"&gt;public string &lt;/span&gt;Name&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;get&lt;/span&gt;;&#xD;
        &lt;span style="color: blue"&gt;set&lt;/span&gt;;&#xD;
    }&#xD;
&#xD;
    &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ImageSource &lt;/span&gt;HeadImg&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;get&lt;/span&gt;;&#xD;
        &lt;span style="color: blue"&gt;set&lt;/span&gt;;&#xD;
    }&#xD;
}&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;我们获取两位牛人的信息：&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;&lt;span style="color: blue"&gt;private &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ObservableCollection&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Person&lt;/span&gt;&amp;gt; GetPersons()&#xD;
{&#xD;
    &lt;span style="color: blue"&gt;return new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ObservableCollection&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Person&lt;/span&gt;&amp;gt;{&#xD;
        &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Person&lt;/span&gt;{&#xD;
            Name=&lt;span style="color: #a31515"&gt;&amp;quot;Bill Gates&amp;quot;&lt;/span&gt;,&#xD;
            HeadImg =  &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;BitmapImage&lt;/span&gt;(&lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Uri&lt;/span&gt;(&lt;span style="color: #a31515"&gt;@&amp;quot;http://album.jinti.com/Stars/UpFiles/FCKFiles/specialreports_2edb_bill_gates.jpg&amp;quot;&lt;/span&gt;))&#xD;
        },&#xD;
        &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Person&lt;/span&gt;{&#xD;
            Name = &lt;span style="color: #a31515"&gt;&amp;quot;Steve Jobs&amp;quot;&lt;/span&gt;,&#xD;
            HeadImg = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;BitmapImage&lt;/span&gt;(&lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Uri&lt;/span&gt;(&lt;span style="color: #a31515"&gt;@&amp;quot;http://photocdn.sohu.com/20080115/Img254675210.jpg&amp;quot;&lt;/span&gt;))&#xD;
        }&#xD;
    };&#xD;
}&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;然后定义了一个按钮以及一个List来显示：&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Button &lt;/span&gt;&lt;span style="color: red"&gt;Content&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Get Persons&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Height&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;24&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Width&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;100&amp;quot; &#xD;
                &lt;/span&gt;&lt;span style="color: red"&gt;HorizontalAlignment&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Left&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Margin&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;10,5,0,0&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Click&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Button_Click&amp;quot; &amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Button&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;ListBox &lt;/span&gt;&lt;span style="color: red"&gt;x&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;Name&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;lstPersons&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Margin&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;10,10,0,0&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Width&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;400&amp;quot;&amp;gt;&#xD;
            &#xD;
        &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;ListBox&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;按钮中的代码:&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;&lt;span style="color: blue"&gt;private void &lt;/span&gt;Button_Click(&lt;span style="color: blue"&gt;object &lt;/span&gt;sender, &lt;span style="color: #2b91af"&gt;RoutedEventArgs &lt;/span&gt;e)&#xD;
{&#xD;
    &lt;span style="color: blue"&gt;var &lt;/span&gt;personList = GetPersons();&#xD;
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.lstPersons.ItemsSource = personList;&#xD;
}&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;看下运行的效果:&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Henllyee/201107/201107171352275313.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Henllyee/201107/201107171352276359.png" width="449" height="105" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;这好像不是我们要的效果,下面我们来做些改变。&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;改善&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;我们需要List里面的信息能够按照我们期望的方式进行现实，我们需要自定义Template:&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;ListBox &lt;/span&gt;&lt;span style="color: red"&gt;x&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;Name&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;lstPersons&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Margin&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;10,10,0,0&amp;quot; &amp;gt;&#xD;
            &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;ListBox.ItemTemplate&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
                &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;DataTemplate&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
                    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Grid&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
                        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Grid.ColumnDefinitions&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
                            &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;ColumnDefinition &lt;/span&gt;&lt;span style="color: red"&gt;Width&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Auto&amp;quot; /&amp;gt;&#xD;
                            &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;ColumnDefinition &lt;/span&gt;&lt;span style="color: red"&gt;Width&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;*&amp;quot; /&amp;gt;&#xD;
                        &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Grid.ColumnDefinitions&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
                        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Image &lt;/span&gt;&lt;span style="color: red"&gt;Height&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;100&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Width&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;100&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Grid.Column&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;0&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Source&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515"&gt;Binding &lt;/span&gt;&lt;span style="color: red"&gt;HeadImg&lt;/span&gt;&lt;span style="color: blue"&gt;}&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Image&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
                        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;TextBlock &lt;/span&gt;&lt;span style="color: red"&gt;Text&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515"&gt;Binding &lt;/span&gt;&lt;span style="color: red"&gt;Name&lt;/span&gt;&lt;span style="color: blue"&gt;}&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;FontSize&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;14&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Margin&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;3&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Grid.Column&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;1&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;TextBlock&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
                    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Grid&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
                &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;DataTemplate&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
            &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;ListBox.ItemTemplate&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
        &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;ListBox&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&#xD;
&lt;/span&gt;&lt;/pre&gt;&#xD;
&#xD;
&#xD;
&#xD;
&lt;p&gt;这下我们来看下运行的效果:&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Henllyee/201107/201107171352288212.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Henllyee/201107/201107171352305572.png" width="239" height="244" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;总结&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;这是Silverlight 4之旅的第一站，下面开始进入详细学习Silverlight中绑定的知识。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/Henllyee/aggbug/2108687.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Henllyee/archive/2011/07/17/Silverlight4-trip-first.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/Henllyee/archive/2011/06/06/net_parallel_programing.html</id><title type="text">.Net 4.0 Parallel 编程之旅</title><summary type="text">在过去的时间里写了9篇Post关于.Net 4.0 Parallel 编程部分的内容，现在整理下，方便自己以后回顾阅读。 首先我们从基础的Loop开始： 1）.Net4.0 Parallel编程（一）Data Parallelism 上 2）.Net4.0 Parallel编程（二）Data Parallelism 中 3）.Net4.0 Parallel编程（三）Data Parallelism下 然后我们看看Task: 1).Net 4.0 Parallel 编程（四） Task(上) 2).Net 4.0 Parallel 编程（五）Task(中) 3).Net 4.0 ...</summary><published>2011-06-06T05:28:00Z</published><updated>2011-06-06T05:28:00Z</updated><author><name>Henry Cui</name><uri>http://www.cnblogs.com/Henllyee/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Henllyee/archive/2011/06/06/net_parallel_programing.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Henllyee/archive/2011/06/06/net_parallel_programing.html"/><content type="html">&lt;p&gt;在过去的时间里写了9篇Post关于.Net 4.0 Parallel 编程部分的内容，现在整理下，方便自己以后回顾阅读。&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;首先我们从基础的Loop开始：&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;1）&lt;a href="http://www.cnblogs.com/Henllyee/archive/2010/05/01/ParallelProgaramming1.html"&gt;.Net4.0 Parallel编程（一）Data Parallelism 上&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;2）&lt;a href="http://www.cnblogs.com/Henllyee/archive/2010/06/09/ParallelProgaramming2.html"&gt;.Net4.0 Parallel编程（二）Data Parallelism 中&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;3）&lt;a href="http://www.cnblogs.com/Henllyee/archive/2010/06/14/ParallelProgaramming3.html"&gt;.Net4.0 Parallel编程（三）Data Parallelism下&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;然后我们看看Task:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;1)&lt;a href="http://www.cnblogs.com/Henllyee/archive/2010/10/18/Parallel_Task.html"&gt;.Net 4.0 Parallel 编程（四） Task(上)&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;2)&lt;a href="http://www.cnblogs.com/Henllyee/archive/2010/10/28/1863923.html"&gt;.Net 4.0 Parallel 编程（五）Task(中)&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;3)&lt;a href="http://www.cnblogs.com/Henllyee/archive/2011/03/27/ParallelProgarmming_Six_Task_3.html"&gt;.Net 4.0 Parallel 编程（六）Task（下）&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;数据同步共享是我们不可回避的问题:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.cnblogs.com/Henllyee/archive/2011/04/07/ParallelProgarmming_Seven_SharingData.html"&gt;.Net 4.0 Parallel 编程（七）Task中的数据共享（上）&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.cnblogs.com/Henllyee/archive/2011/04/12/ParallelProgarmming_Eight_SharingData.html"&gt;.Net 4.0 Parallel编程（八）Task中的数据共享（中）&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.cnblogs.com/Henllyee/archive/2011/04/21/ParallelProgarmming_Nine_SharingData.html"&gt;.Net 4.0 Parallel 编程（九）Task中的数据共享（下）&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Parallel 中的Linq&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;.Net 4.0 Parallel 编程（十）PLinq(上)&lt;/p&gt;  &lt;p&gt;.Net 4.0 Parallel 编程（十一）PLinq(下)&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Parallel中的扩展&lt;/strong&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/Henllyee/aggbug/2073603.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Henllyee/archive/2011/06/06/net_parallel_programing.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/Henllyee/archive/2011/04/21/ParallelProgarmming_Nine_SharingData.html</id><title type="text">.Net 4.0 Parallel 编程（九）Task中的数据共享（下）</title><summary type="text">在上篇Post中我们看过了几种常用的同步类型，本篇文章会介绍下申明性的同步的实现以及对于集合类型数据共享的问题，首先看下申明性同步的实现。 申明性同步 我们可以通过使用Synchronization 特性来标识一个类，从而使一个类型的字段以及方法都实现同步化。在使用Synchronization 时，我们需要将我们的目标同步的类继承于System.ContextBoundObject类型。我们来看看之前的例子我们同步标识Synchronization 的实现： [Synchronization]class SumClass : ContextBoundObject{ private int _</summary><published>2011-04-21T02:17:00Z</published><updated>2011-04-21T02:17:00Z</updated><author><name>Henry Cui</name><uri>http://www.cnblogs.com/Henllyee/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Henllyee/archive/2011/04/21/ParallelProgarmming_Nine_SharingData.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Henllyee/archive/2011/04/21/ParallelProgarmming_Nine_SharingData.html"/><content type="html">&lt;p&gt;在上篇Post中我们看过了几种常用的同步类型，本篇文章会介绍下申明性的同步的实现以及对于集合类型数据共享的问题，首先看下申明性同步的实现。&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;申明性同步&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;我们可以通过使用Synchronization 特性来标识一个类，从而使一个类型的字段以及方法都实现同步化。在使用Synchronization 时，我们需要将我们的目标同步的类继承于System.ContextBoundObject类型。我们来看看之前的例子我们同步标识Synchronization 的实现：&lt;/p&gt;  &lt;pre &gt;[&lt;span style="color: #2b91af"&gt;Synchronization&lt;/span&gt;]&#xD;
&lt;span style="color: blue"&gt;class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SumClass &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;ContextBoundObject&#xD;
&lt;/span&gt;{&#xD;
    &lt;span style="color: blue"&gt;private int &lt;/span&gt;_Sum;&#xD;
&#xD;
    &lt;span style="color: blue"&gt;public void &lt;/span&gt;Increment()&#xD;
    {&#xD;
        _Sum++;&#xD;
    }&#xD;
&#xD;
    &lt;span style="color: blue"&gt;public int &lt;/span&gt;GetSum()&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;return &lt;/span&gt;_Sum;&#xD;
    }&#xD;
}&#xD;
&lt;span style="color: blue"&gt;class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Program&#xD;
&lt;/span&gt;{&#xD;
    &lt;span style="color: blue"&gt;static void &lt;/span&gt;Main(&lt;span style="color: blue"&gt;string&lt;/span&gt;[] args)&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;var &lt;/span&gt;sum = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SumClass&lt;/span&gt;();&#xD;
        &lt;span style="color: #2b91af"&gt;Task&lt;/span&gt;[] tasks = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Task&lt;/span&gt;[10];&#xD;
        &lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;int &lt;/span&gt;i = 0; i &amp;lt; 10; i++)&#xD;
        {&#xD;
            tasks[i] = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Task&lt;/span&gt;(() =&amp;gt;&#xD;
            {&#xD;
                &lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;int &lt;/span&gt;j = 0; j &amp;lt; 1000; j++)&#xD;
                {&#xD;
                    sum.Increment();&#xD;
                }&#xD;
            });&#xD;
            tasks[i].Start();&#xD;
        }&#xD;
        &lt;span style="color: #2b91af"&gt;Task&lt;/span&gt;.WaitAll(tasks);&#xD;
        &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;Expected value {0}, Parallel value: {1}&amp;quot;&lt;/span&gt;,&#xD;
        10000, sum.GetSum());&#xD;
        &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.ReadLine();&#xD;
    }&#xD;
}&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;并发集合&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;在某些时候我们需要并发的操作集合类型，对于集合类型也存在数据共享的问题，我们来看一个例子，在例子中我们创建一个队列，然后多个Task同步进行出队列操作，看会不会出现同步出一个元素的情况，其中我们通过一个计数器进行统计出队列的次数：&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;&lt;span style="color: blue"&gt;static void &lt;/span&gt;Main(&lt;span style="color: blue"&gt;string&lt;/span&gt;[] args)&#xD;
{&#xD;
    &lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;j = 0; j &amp;lt; 10; j++)&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;var &lt;/span&gt;queue = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Queue&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;&amp;gt;();&#xD;
        &lt;span style="color: blue"&gt;var &lt;/span&gt;count = 0;&#xD;
        &lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;i = 0; i &amp;lt; 1000; i++)&#xD;
        {&#xD;
            queue.Enqueue(i);&#xD;
        }&#xD;
        &lt;span style="color: blue"&gt;var &lt;/span&gt;tasks = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Task&lt;/span&gt;[10];&#xD;
        &lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;i = 0; i &amp;lt; tasks.Length; i++)&#xD;
        {&#xD;
            tasks[i] = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Task&lt;/span&gt;(() =&amp;gt;&#xD;
            {&#xD;
                &lt;span style="color: blue"&gt;while &lt;/span&gt;(queue.Count &amp;gt; 0)&#xD;
                {&#xD;
                    &lt;span style="color: blue"&gt;var &lt;/span&gt;item = queue.Dequeue();&#xD;
                    &lt;span style="color: #2b91af"&gt;Interlocked&lt;/span&gt;.Increment(&lt;span style="color: blue"&gt;ref &lt;/span&gt;count);&#xD;
                }&#xD;
            });&#xD;
            tasks[i].Start();&#xD;
        }&#xD;
        &lt;span style="color: blue"&gt;try&#xD;
        &lt;/span&gt;{&#xD;
            &lt;span style="color: #2b91af"&gt;Task&lt;/span&gt;.WaitAll(tasks);&#xD;
        }&#xD;
        &lt;span style="color: blue"&gt;catch &lt;/span&gt;(&lt;span style="color: #2b91af"&gt;AggregateException &lt;/span&gt;e)&#xD;
        {&#xD;
            e.Handle((ex) =&amp;gt;&#xD;
            {&#xD;
                &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;Exception Message:{0}&amp;quot;&lt;/span&gt;,ex.Message);&#xD;
                &lt;span style="color: blue"&gt;return true&lt;/span&gt;;&#xD;
            });&#xD;
        }&#xD;
        &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;Dequeue items count :{0}&amp;quot;&lt;/span&gt;, count);&#xD;
    }&#xD;
    &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.ReadKey();&#xD;
}&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;在上面的示例中，我们为了让效果更佳明显，看十次运行的结果：&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Henllyee/201104/201104211017142868.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Henllyee/201104/201104211017164131.png" width="283" height="221" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;在上面我们看到两个问题：1.出队列的次数超过了1000个；2.出现异常消息已经为空。出现这两个异常的原因是：1.多个线程同时在操作一个元素进行出的动作；2消息为空是因为当队列中剩下最后一个元素时，某个线程在访问“queue.Count &amp;gt; 0”时确实是大于0的，所以进入循环代码中准备进行出队列动作，而另外一个线程也进入循环中，已经将队列中出完了，就出现了数据争用的情况。&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;在.Net 4.0中提供了很多并发的集合类型来让我们处理数据同步的集合的问题，这里面包括：&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;1.ConcurrentQueue：提供并发安全的队列集合，以先进先出的方式进行操作；&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;2.ConcurrentStack：提供并发安全的堆栈集合，以先进后出的方式进行操作；&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;3.ConcurrentBag：提供并发安全的一种特殊的排序的集合；&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;4.ConcurrentDictionary：提供并发安全的一种key-value类型的集合。&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;我们在这里只做ConcurrentQueue的一个尝试，并发队列是一种线程安全的队列集合，我们可以通过Enqueue()进行排队、TryDequeue()进行出队列操作，在上面的例子中我们使用ConcurrentQueue时：&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;&lt;span style="color: blue"&gt;static void &lt;/span&gt;Main(&lt;span style="color: blue"&gt;string&lt;/span&gt;[] args)&#xD;
{&#xD;
    &lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;j = 0; j &amp;lt; 10; j++)&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;var &lt;/span&gt;queue = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ConcurrentQueue&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;&amp;gt;();&#xD;
        &lt;span style="color: blue"&gt;var &lt;/span&gt;count = 0;&#xD;
        &lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;i = 0; i &amp;lt; 1000; i++)&#xD;
        {&#xD;
            queue.Enqueue(i);&#xD;
        }&#xD;
        &lt;span style="color: blue"&gt;var &lt;/span&gt;tasks = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Task&lt;/span&gt;[10];&#xD;
        &lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;i = 0; i &amp;lt; tasks.Length; i++)&#xD;
        {&#xD;
            tasks[i] = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Task&lt;/span&gt;(() =&amp;gt;&#xD;
            {&#xD;
                &lt;span style="color: blue"&gt;while &lt;/span&gt;(queue.Count &amp;gt; 0)&#xD;
                {&#xD;
                    &lt;span style="color: blue"&gt;int &lt;/span&gt;item;&#xD;
                    &lt;span style="color: blue"&gt;var &lt;/span&gt;isDequeue = queue.TryDequeue(&lt;span style="color: blue"&gt;out &lt;/span&gt;item);&#xD;
                    &lt;span style="color: blue"&gt;if&lt;/span&gt;(isDequeue) &lt;span style="color: #2b91af"&gt;Interlocked&lt;/span&gt;.Increment(&lt;span style="color: blue"&gt;ref &lt;/span&gt;count);&#xD;
                }&#xD;
            });&#xD;
            tasks[i].Start();&#xD;
        }&#xD;
        &lt;span style="color: blue"&gt;try&#xD;
        &lt;/span&gt;{&#xD;
            &lt;span style="color: #2b91af"&gt;Task&lt;/span&gt;.WaitAll(tasks);&#xD;
        }&#xD;
        &lt;span style="color: blue"&gt;catch &lt;/span&gt;(&lt;span style="color: #2b91af"&gt;AggregateException &lt;/span&gt;e)&#xD;
        {&#xD;
            e.Handle((ex) =&amp;gt;&#xD;
            {&#xD;
                &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;Exception Message:{0}&amp;quot;&lt;/span&gt;,ex.Message);&#xD;
                &lt;span style="color: blue"&gt;return true&lt;/span&gt;;&#xD;
            });&#xD;
        }&#xD;
        &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;Dequeue items count :{0}&amp;quot;&lt;/span&gt;, count);&#xD;
    }&#xD;
    &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.ReadKey();&#xD;
}&lt;/pre&gt;&#xD;
&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;总结&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;在本文中看过了数据共享中如何使用Synchronization 进行申明性同步，以及同步集合的一些介绍，希望对您有帮助。到此，Task中的数据共享就介绍结束了，下面我们看下PLinq中的内容。&lt;/p&gt;&#xD;
&#xD;
&lt;div style="border-bottom: #cac8ca 1px dotted; border-left: #cac8ca 1px dotted; width: 100%; height: 70px; border-top: #cac8ca 1px dotted; border-right: #cac8ca 1px dotted"&gt;&#xD;
  &lt;div style="float: left"&gt;&lt;img alt="alt" src="http://images.cnblogs.com/cnblogs_com/henllyee/png-1665.png" /&gt; &lt;/div&gt;&#xD;
&#xD;
  &lt;div style="margin-top: 2px; float: left; margin-left: 20px; font-size: 12px"&gt;&lt;span style="line-height: 20px; height: 20px"&gt;作者：Henry Cui&lt;/span&gt; &#xD;
&#xD;
    &lt;br /&gt;&lt;span style="line-height: 20px; height: 20px"&gt;出处： &lt;a style="color: #ff0000; text-decoration: none" href="http://henllyee.cnblogs.com/"&gt;http://henllyee.cnblogs.com/&lt;/a&gt; &lt;/span&gt;&#xD;
&#xD;
    &lt;br /&gt;&lt;span style="line-height: 20px; height: 20px"&gt;本文版权归作者和博客园共有，欢迎转载，但未经作者同意必须保留此段声明。 &lt;/span&gt;&lt;/div&gt;&#xD;
&lt;/div&gt;&lt;img src="http://www.cnblogs.com/Henllyee/aggbug/2023234.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Henllyee/archive/2011/04/21/ParallelProgarmming_Nine_SharingData.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/Henllyee/archive/2011/04/12/ParallelProgarmming_Eight_SharingData.html</id><title type="text">.Net 4.0 Parallel编程（八）Task中的数据共享（中）</title><summary type="text">在上篇文章中我们看过了多线程中的数据共享问题，以及通过分离执行来解决的办法。本篇文章就数据共享的同步处理中的一些常见的方法进行一些介绍。 数据同步时的步骤 我之前的文章我们对数据共享问题处理的方式是“分离执行”，我们通过把每个Task执行完成后的各自计算的值进行最后的汇总，也就是说多个Task之间不存在数据共享了，各自做各自的事，完全分离开来。可是这毕竟不是我们常规的处理办法，这样我们会花更多的经历在分离上。其实我们主要的数据共享在Sum上： for (int j = 0; j &amp;lt; 1000; j++){ Sum++;}那我们可以通过一种有序的机制来访问Sum，即当一个Task在进行Su</summary><published>2011-04-12T14:41:00Z</published><updated>2011-04-12T14:41:00Z</updated><author><name>Henry Cui</name><uri>http://www.cnblogs.com/Henllyee/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Henllyee/archive/2011/04/12/ParallelProgarmming_Eight_SharingData.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Henllyee/archive/2011/04/12/ParallelProgarmming_Eight_SharingData.html"/><content type="html">&lt;p&gt;在上篇文章中我们看过了多线程中的数据共享问题，以及通过分离执行来解决的办法。本篇文章就数据共享的同步处理中的一些常见的方法进行一些介绍。&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;数据同步时的步骤&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;我之前的文章我们对数据共享问题处理的方式是“&lt;a href="http://www.cnblogs.com/Henllyee/archive/2011/04/07/ParallelProgarmming_Seven_SharingData.html"&gt;分离执行&lt;/a&gt;”，我们通过把每个Task执行完成后的各自计算的值进行最后的汇总，也就是说多个Task之间不存在数据共享了，各自做各自的事，完全分离开来。可是这毕竟不是我们常规的处理办法，这样我们会花更多的经历在分离上。其实我们主要的数据共享在Sum上：&lt;/p&gt;  &lt;pre &gt;&lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;int &lt;/span&gt;j = 0; j &amp;lt; 1000; j++)&#xD;
{&#xD;
    Sum++;&#xD;
}&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;那我们可以通过一种有序的机制来访问Sum，即当一个Task在进行Sum访问时，其它的Task做等待，从达成对Sum的有序访问，避免对Sum的争用。准备做同步处理时，我们一般要做两个步骤：&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;1）确定数据共享的临界区域&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;2）确定使用的同步的类型&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;比如在之前的例子中，For语句中的Sum++就是临界区域，在这个地方可能会出现对Sum的争用。所以我们可以确定For语句中的区域为一个数据共享的临界区域。确定完成临界区域之后，我们需要决定使用那种同步的类型。这里首先解释下什么是同步类型，同步类型是一种用来调度Task访问临界区域的一种特殊类型。在.Net 4.0中提供了多种同步类型给我们使用，主要分为：轻量级的、重量级的和等待处理型的，在下面我们会介绍常用的同步处理类型。&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;常用的同步类型&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;首先来看看.Net 4.0中常见的几种同步类型以及处理的相关问题：&lt;/p&gt;&#xD;
&#xD;
&lt;table border="1" bordercolor="#000000" bordercolorlight="#ffffff" bordercolordark="#ffffff" width="100%" bgcolor="#ffffff"&gt;&lt;tbody&gt;&#xD;
    &lt;tr&gt;&#xD;
      &lt;td&gt;同步类型&lt;/td&gt;&#xD;
&#xD;
      &lt;td&gt;解决问题&lt;/td&gt;&#xD;
    &lt;/tr&gt;&#xD;
&#xD;
    &lt;tr&gt;&#xD;
      &lt;td&gt;lock关键字、Montor类、SpinLock类&lt;/td&gt;&#xD;
&#xD;
      &lt;td&gt;有序访问临界区域&lt;/td&gt;&#xD;
    &lt;/tr&gt;&#xD;
&#xD;
    &lt;tr&gt;&#xD;
      &lt;td&gt;Interlocked类&lt;/td&gt;&#xD;
&#xD;
      &lt;td&gt;数值类型的增加或则减少&lt;/td&gt;&#xD;
    &lt;/tr&gt;&#xD;
&#xD;
    &lt;tr&gt;&#xD;
      &lt;td&gt;Mutex类&lt;/td&gt;&#xD;
&#xD;
      &lt;td&gt;交叉同步&lt;/td&gt;&#xD;
    &lt;/tr&gt;&#xD;
&#xD;
    &lt;tr&gt;&#xD;
      &lt;td&gt;WaitAll方法&lt;/td&gt;&#xD;
&#xD;
      &lt;td&gt;同步多个锁定（主要是Task之间的调度）&lt;/td&gt;&#xD;
    &lt;/tr&gt;&#xD;
&#xD;
    &lt;tr&gt;&#xD;
      &lt;td&gt;申明性的同步（如Synchronization）&lt;/td&gt;&#xD;
&#xD;
      &lt;td&gt;使类中的所有的方法同步&lt;/td&gt;&#xD;
    &lt;/tr&gt;&#xD;
  &lt;/tbody&gt;&lt;/table&gt;&#xD;
&#xD;
&lt;p&gt;下面我们就详细常见的同步类型的使用：&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;Lock&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;其实最简单同步类型的使用办法就是使用Lock关键字。在使用lock关键字时，首先我们需要创建一个锁定的object，而且这个object需要所有的task都能访问，其次能我们需要将我们的临界区域包含在lock块中。我们之前例子中代码可以这样加上lock:&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;&lt;span style="color: blue"&gt;int &lt;/span&gt;Sum = 0;&#xD;
&lt;span style="color: #2b91af"&gt;Task&lt;/span&gt;[] tasks = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Task&lt;/span&gt;[10];&#xD;
&lt;span style="color: blue"&gt;var &lt;/span&gt;obj = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Object&lt;/span&gt;();&#xD;
&lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;int &lt;/span&gt;i = 0; i &amp;lt; 10; i++)&#xD;
{&#xD;
    tasks[i] = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Task&lt;/span&gt;(() =&amp;gt;&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;int &lt;/span&gt;j = 0; j &amp;lt; 1000; j++)&#xD;
        {&#xD;
            &lt;span style="color: blue"&gt;lock &lt;/span&gt;(obj)&#xD;
            {&#xD;
                Sum = Sum + 1;&#xD;
            }&#xD;
        }&#xD;
    });&#xD;
    tasks[i].Start();&#xD;
}&#xD;
&lt;span style="color: #2b91af"&gt;Task&lt;/span&gt;.WaitAll(tasks);&#xD;
&lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;Expected value {0}, Parallel value: {1}&amp;quot;&lt;/span&gt;,&#xD;
10000, Sum);&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;其实lock关键字是使用Monitor的一种简短的方式，其实上面的Lock部分可以理解成：&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;&lt;span style="color: blue"&gt;try&#xD;
&lt;/span&gt;{&#xD;
    &lt;span style="color: #2b91af"&gt;Monitor&lt;/span&gt;.Enter(obj,&lt;span style="color: blue"&gt;ref &lt;/span&gt;lockAcquired);&#xD;
    Sum = Sum + 1;&#xD;
}&#xD;
&lt;span style="color: blue"&gt;finally &lt;/span&gt;{&#xD;
    &lt;span style="color: blue"&gt;if &lt;/span&gt;(lockAcquired) &lt;span style="color: #2b91af"&gt;Monitor&lt;/span&gt;.Exit(obj);&#xD;
}&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;lock关键字自动通过调用Monitor.Enter,Monitor.Exit方法来处理获得锁以及释放锁，在Enter方法中传递了bool值类型的参数，这个参数会在获得锁之后设置成True，我们在调用Exit是需要确认这个参数的值的。 &lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;Interlocked&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;Interlocked其实在&lt;a href="http://www.cnblogs.com/Henllyee/archive/2010/06/09/ParallelProgaramming2.html"&gt;之前的文章&lt;/a&gt;的我们已经使用过,Interlocked通过使用操作系统或则硬件的一些特性提供了一些列高效的静态的同步方法。其中主要提供了这些方法：Exchange、Add、Increment、CompareExchange四种类型的多个方法的重载。我们将上面的例子中使用Interlocked:&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;&lt;span style="color: blue"&gt;int &lt;/span&gt;Sum = 0;&#xD;
&lt;span style="color: #2b91af"&gt;Task&lt;/span&gt;[] tasks = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Task&lt;/span&gt;[10];&#xD;
&lt;span style="color: blue"&gt;var &lt;/span&gt;obj = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Object&lt;/span&gt;();&#xD;
&lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;int &lt;/span&gt;i = 0; i &amp;lt; 10; i++)&#xD;
{&#xD;
    tasks[i] = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Task&lt;/span&gt;(() =&amp;gt;&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;int &lt;/span&gt;j = 0; j &amp;lt; 1000; j++)&#xD;
        {&#xD;
            &lt;span style="color: #2b91af"&gt;Interlocked&lt;/span&gt;.Increment(&lt;span style="color: blue"&gt;ref &lt;/span&gt;Sum);&#xD;
        }&#xD;
    });&#xD;
    tasks[i].Start();&#xD;
}&#xD;
&lt;span style="color: #2b91af"&gt;Task&lt;/span&gt;.WaitAll(tasks);&#xD;
&lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;Expected value {0}, Parallel value: {1}&amp;quot;&lt;/span&gt;,&#xD;
10000, Sum);&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;Mutex&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;Mutex也是一个同步类型，在多个线程进行访问的时候，它只向一个线程授权共享数据的独立访问。我们可以通过Mutex中的WaitOne方法来获取Mutex的所有权，但是同时我们要注意的是，我们在一个线程中多少次调用过WaitOne方法，就需要调用多少次ReleaseMutex方法来释放Mutex的占有。上面的例子我们通过Mutex这样实现：&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;&lt;span style="color: blue"&gt;int &lt;/span&gt;Sum = 0;&#xD;
&lt;span style="color: #2b91af"&gt;Task&lt;/span&gt;[] tasks = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Task&lt;/span&gt;[10];&#xD;
&lt;span style="color: blue"&gt;var &lt;/span&gt;mutex = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Mutex&lt;/span&gt;();&#xD;
&lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;int &lt;/span&gt;i = 0; i &amp;lt; 10; i++)&#xD;
{&#xD;
    tasks[i] = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Task&lt;/span&gt;(() =&amp;gt;&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;int &lt;/span&gt;j = 0; j &amp;lt; 1000; j++)&#xD;
        {&#xD;
            &lt;span style="color: blue"&gt;bool &lt;/span&gt;lockAcquired = mutex.WaitOne();&#xD;
            &lt;span style="color: blue"&gt;try&#xD;
            &lt;/span&gt;{&#xD;
                Sum++;&#xD;
            }&#xD;
            &lt;span style="color: blue"&gt;finally&#xD;
            &lt;/span&gt;{&#xD;
                &lt;span style="color: blue"&gt;if &lt;/span&gt;(lockAcquired) mutex.ReleaseMutex();&#xD;
            }&#xD;
        }&#xD;
    });&#xD;
    tasks[i].Start();&#xD;
}&#xD;
&lt;span style="color: #2b91af"&gt;Task&lt;/span&gt;.WaitAll(tasks);&#xD;
&lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;Expected value {0}, Parallel value: {1}&amp;quot;&lt;/span&gt;,&#xD;
10000, Sum);&lt;/pre&gt;&#xD;
&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;同步类型使用建议&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;在上面的我们已经介绍过了三种同步类型的使用，其中想Lock这样的关键字是轻量级的，而Monitor则是重量级的，需要我们自己进行手动的获取锁释放锁，在使用同步类型的时候建议大家选择轻量级的类型。下面有几点建议让大家更加高效地同步：&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;1.更多的使用轻量级的同步类型&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;2.尽量不要使用自定义同步类型&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;3.不要同步得太多也不要同步得太少&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;总结&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;在本篇文章我们看过如何进行Task中的一些同步处理，同时看过常用的三种同步类型，希望对大家有帮助。在下篇文章中会介绍下其他的一些同步处理，以及一些常见的问题的处理。&lt;/p&gt;&#xD;
&#xD;
&lt;div style="border-bottom: #cac8ca 1px dotted; border-left: #cac8ca 1px dotted; width: 100%; height: 70px; border-top: #cac8ca 1px dotted; border-right: #cac8ca 1px dotted"&gt;&#xD;
  &lt;div style="float: left"&gt;&lt;img alt="alt" src="http://images.cnblogs.com/cnblogs_com/henllyee/png-1665.png" /&gt; &lt;/div&gt;&#xD;
&#xD;
  &lt;div style="margin-top: 2px; float: left; margin-left: 20px; font-size: 12px"&gt;&lt;span style="line-height: 20px; height: 20px"&gt;作者：Henry Cui&lt;/span&gt; &#xD;
&#xD;
    &lt;br /&gt;&lt;span style="line-height: 20px; height: 20px"&gt;出处： &lt;a style="color: #ff0000; text-decoration: none" href="http://henllyee.cnblogs.com/"&gt;http://henllyee.cnblogs.com/&lt;/a&gt; &lt;/span&gt;&#xD;
&#xD;
    &lt;br /&gt;&lt;span style="line-height: 20px; height: 20px"&gt;本文版权归作者和博客园共有，欢迎转载，但未经作者同意必须保留此段声明。 &lt;/span&gt;&lt;/div&gt;&#xD;
&lt;/div&gt;&lt;img src="http://www.cnblogs.com/Henllyee/aggbug/2014198.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Henllyee/archive/2011/04/12/ParallelProgarmming_Eight_SharingData.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/Henllyee/archive/2011/04/07/ParallelProgarmming_Seven_SharingData.html</id><title type="text">.Net 4.0 Parallel 编程（七）Task中的数据共享（上）</title><summary type="text">在前几篇文章中我们看过Parallel Loop以及Task 部分内容，而在多线程的编程中我们较为痛疼的就是多线程中的数据共享问题以及数据同步的问题。本篇Post以及后面的几篇Post中会探讨下TPL中数据共享的常见问题以及其常规的解决办法。 引例 首先我们来看下面的一段代码： static void Main(string[] args){ int Sum = 0; Task[] tasks = new Task[10]; for (int i = 0; i &amp;lt; 10; i++) { tasks[i] = new Task(() =&amp;gt; { for (int j = 0; j &amp;l</summary><published>2011-04-07T05:08:00Z</published><updated>2011-04-07T05:08:00Z</updated><author><name>Henry Cui</name><uri>http://www.cnblogs.com/Henllyee/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Henllyee/archive/2011/04/07/ParallelProgarmming_Seven_SharingData.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Henllyee/archive/2011/04/07/ParallelProgarmming_Seven_SharingData.html"/><content type="html">&lt;p&gt;在前几篇文章中我们看过Parallel Loop以及Task 部分内容，而在多线程的编程中我们较为痛疼的就是多线程中的数据共享问题以及数据同步的问题。本篇Post以及后面的几篇Post中会探讨下TPL中数据共享的常见问题以及其常规的解决办法。&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;引例&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;首先我们来看下面的一段代码：&lt;/p&gt;  &lt;pre &gt;&lt;span style="color: blue"&gt;static void &lt;/span&gt;Main(&lt;span style="color: blue"&gt;string&lt;/span&gt;[] args)&#xD;
{&#xD;
    &lt;span style="color: blue"&gt;int &lt;/span&gt;Sum = 0;&#xD;
    &lt;span style="color: #2b91af"&gt;Task&lt;/span&gt;[] tasks = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Task&lt;/span&gt;[10];&#xD;
    &lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;int &lt;/span&gt;i = 0; i &amp;lt; 10; i++)&#xD;
    {&#xD;
        tasks[i] = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Task&lt;/span&gt;(() =&amp;gt;&#xD;
        {&#xD;
            &lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;int &lt;/span&gt;j = 0; j &amp;lt; 1000; j++)&#xD;
            {&#xD;
                Sum = Sum + 1;&#xD;
            }&#xD;
        });&#xD;
        tasks[i].Start();&#xD;
    }&#xD;
    &lt;span style="color: #2b91af"&gt;Task&lt;/span&gt;.WaitAll(tasks);&#xD;
    &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;Expected value {0}, Parallel value: {1}&amp;quot;&lt;/span&gt;,&#xD;
    10000, Sum);&#xD;
    &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.ReadLine();&#xD;
}&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;上面的代码我们期望是得到10个线程对Sum数据进行轮询累加，按照我们期望的情况，算出的结果应该是：10000，可是我们看看运行后的结果：&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Henllyee/201104/201104071308027762.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Henllyee/201104/201104071308023128.png" width="399" height="70" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;这是为什么呢？其实我们想想就会明白，主要是我们多个线程并行的进行了Sum的操作，我们可以通过一个时序图来看表示小两个线程同时操作Sum会出现的状况（下图中的表述可能不正确，请谅解）：&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&amp;#160;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Henllyee/201104/20110407130802337.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Henllyee/201104/201104071308037861.png" width="502" height="474" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;在Task1获取到sum值为0，Task2也获取到0，而两个Task都执行了0+1的操作之后并记录入Sum中，而不是我们预期的线程之间各自计算后的信息也进行累加。在我们在并行编程时，像这类数据共享问题是非常常见的。在上面的问题中，我们可以通过顺序执行的来解决这个问题，但是这不是我们希望的，毕竟我们还是希望以并行的方式去处理。在TPL中提供了分离执行的方法来解决这个问题。&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;分离执行&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;我们可以通过Task中传递的state参数来进行隔离执行：&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;&lt;span style="color: blue"&gt;static void &lt;/span&gt;Main(&lt;span style="color: blue"&gt;string&lt;/span&gt;[] args)&#xD;
{&#xD;
    &lt;span style="color: blue"&gt;int &lt;/span&gt;Sum = 0;&#xD;
    &lt;span style="color: #2b91af"&gt;Task&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;&amp;gt;[] tasks = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Task&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;&amp;gt;[10];&#xD;
    &lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;int &lt;/span&gt;i = 0; i &amp;lt; 10; i++)&#xD;
    {&#xD;
        tasks[i] = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Task&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;&amp;gt;((obj) =&amp;gt;&#xD;
        {&#xD;
            &lt;span style="color: blue"&gt;var &lt;/span&gt;start = (&lt;span style="color: blue"&gt;int&lt;/span&gt;)obj;&#xD;
            &lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;int &lt;/span&gt;j = 0; j &amp;lt; 1000; j++)&#xD;
            {&#xD;
                start = start + 1;&#xD;
            }&#xD;
            &lt;span style="color: blue"&gt;return &lt;/span&gt;start;&#xD;
        }, Sum);&#xD;
        tasks[i].Start();&#xD;
    }&#xD;
    &lt;span style="color: #2b91af"&gt;Task&lt;/span&gt;.WaitAll(tasks);&#xD;
    &lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;i = 0; i &amp;lt; 10; i++)&#xD;
    {&#xD;
        Sum += tasks[i].Result;&#xD;
    }&#xD;
    &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;Expected value {0}, Parallel value: {1}&amp;quot;&lt;/span&gt;,&#xD;
    10000, Sum);&#xD;
    &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.ReadLine();&#xD;
}&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;上面的程序里面我们在每个Task执行时就不存在数据共享了，每个Task中计算自己值，最后我们汇总每个Task的Result。似乎我们的问题已经解决了，但是我们要知道在.Net 运行时里面并没有支持分离。也就是说，每次我们操作Task时，都要保证Task之间是没有数据共享的，确实是件麻烦的事。在.Net中提供了System.Threading.ThreadLocal来创建分离。&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;ThreadLocal&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;ThreadLocal是一种提供线程本地存储的类型，它可以给每个线程一个分离的实例，来提供每个线程单独的数据结果。上面的程序我们可以使用TreadLocal：&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;&lt;span style="color: blue"&gt;static void &lt;/span&gt;Main(&lt;span style="color: blue"&gt;string&lt;/span&gt;[] args)&#xD;
{&#xD;
    &lt;span style="color: blue"&gt;int &lt;/span&gt;Sum = 0;&#xD;
    &lt;span style="color: #2b91af"&gt;Task&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;&amp;gt;[] tasks = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Task&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;&amp;gt;[10];&#xD;
    &lt;span style="color: blue"&gt;var &lt;/span&gt;tl = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ThreadLocal&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;&amp;gt;();&#xD;
    &lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;int &lt;/span&gt;i = 0; i &amp;lt; 10; i++)&#xD;
    {&#xD;
        tasks[i] = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Task&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;&amp;gt;((obj) =&amp;gt;&#xD;
        {&#xD;
            tl.Value = (&lt;span style="color: blue"&gt;int&lt;/span&gt;)obj;&#xD;
            &lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;int &lt;/span&gt;j = 0; j &amp;lt; 1000; j++)&#xD;
            {&#xD;
                tl.Value++;&#xD;
            }&#xD;
            &lt;span style="color: blue"&gt;return &lt;/span&gt;tl.Value;&#xD;
        }, Sum);&#xD;
        tasks[i].Start();&#xD;
    }&#xD;
    &lt;span style="color: #2b91af"&gt;Task&lt;/span&gt;.WaitAll(tasks);&#xD;
    &lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;i = 0; i &amp;lt; 10; i++)&#xD;
    {&#xD;
        Sum += tasks[i].Result;&#xD;
    }&#xD;
    &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;Expected value {0}, Parallel value: {1}&amp;quot;&lt;/span&gt;,&#xD;
    10000, Sum);&#xD;
    &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.ReadLine();&#xD;
}&lt;/pre&gt;&#xD;
&#xD;
&#xD;
&#xD;
&lt;p&gt;但是我们要注意的一点TreadLocal是针对每个线程的，不是针对每个Task的。在TreadLocal构造函数中提供了一个重载的方法，以让我们来设置每个线程Result初始值。我们通过下面的例子来看看：&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;&lt;span style="color: blue"&gt;static void &lt;/span&gt;Main(&lt;span style="color: blue"&gt;string&lt;/span&gt;[] args)&#xD;
{&#xD;
    &lt;span style="color: blue"&gt;int &lt;/span&gt;Sum = 0;&#xD;
    &lt;span style="color: #2b91af"&gt;Task&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;&amp;gt;[] tasks = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Task&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;&amp;gt;[10];&#xD;
    &lt;span style="color: blue"&gt;var &lt;/span&gt;tl = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ThreadLocal&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;&amp;gt;(() =&amp;gt; {&#xD;
        &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(Sum);&#xD;
        &lt;span style="color: blue"&gt;return &lt;/span&gt;Sum;&#xD;
    });&#xD;
    &lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;int &lt;/span&gt;i = 0; i &amp;lt; 10; i++)&#xD;
    {&#xD;
        tasks[i] = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Task&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;&amp;gt;(() =&amp;gt;&#xD;
        {&#xD;
            &lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;int &lt;/span&gt;j = 0; j &amp;lt; 1000; j++)&#xD;
            {&#xD;
                tl.Value++;&#xD;
            }&#xD;
            &lt;span style="color: blue"&gt;return &lt;/span&gt;tl.Value;&#xD;
        });&#xD;
        tasks[i].Start();&#xD;
    }&#xD;
    &lt;span style="color: #2b91af"&gt;Task&lt;/span&gt;.WaitAll(tasks);&#xD;
    &lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;i = 0; i &amp;lt; 10; i++)&#xD;
    {&#xD;
        Sum += tasks[i].Result;&#xD;
    }&#xD;
    &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;Expected value {0}, Parallel value: {1}&amp;quot;&lt;/span&gt;,&#xD;
    10000, Sum);&#xD;
    &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.ReadLine();&#xD;
}&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;我们来看看执行的结果：&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Henllyee/201104/201104071308035702.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Henllyee/201104/201104071308032355.png" width="360" height="108" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;大家可能有疑问，我们是创建了10个Task，可是ThreadLocal只进行了4次初始化。我们要记住一点Task不是Thread，一个Tread中可能有多个Task。我Demo的机器是四核的，这里开启了四个线程去执行10个Task。之所以我们看到的结果会不对，是因为，在一个线程里面会有多个Task,每个Task之间计算时，第一Task计算出来的结果会传递给下一个Task，从而进行了一次累加，所以会出现计算出来的值不准确。所以ThreadLocal是魔鬼也是天使，我们在使用时也要额外注意。&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;总结&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;在本文中通过引例我们看到了多线程中数据共享的问题，以及了解了分离执行的办法，同时也了解了TreadLocal的原理，希望对您有用。下篇文章会就TPL中的数据共享问题进行继续地探讨。&lt;/p&gt;&#xD;
&#xD;
&lt;div style="border-bottom: #cac8ca 1px dotted; border-left: #cac8ca 1px dotted; width: 100%; height: 70px; border-top: #cac8ca 1px dotted; border-right: #cac8ca 1px dotted"&gt;&#xD;
  &lt;div style="float: left"&gt;&lt;img alt="alt" src="http://images.cnblogs.com/cnblogs_com/henllyee/png-1665.png" /&gt; &lt;/div&gt;&#xD;
&#xD;
  &lt;div style="margin-top: 2px; float: left; margin-left: 20px; font-size: 12px"&gt;&lt;span style="line-height: 20px; height: 20px"&gt;作者：Henry Cui&lt;/span&gt; &#xD;
&#xD;
    &lt;br /&gt;&lt;span style="line-height: 20px; height: 20px"&gt;出处： &lt;a style="color: #ff0000; text-decoration: none" href="http://henllyee.cnblogs.com/"&gt;http://henllyee.cnblogs.com/&lt;/a&gt; &lt;/span&gt;&#xD;
&#xD;
    &lt;br /&gt;&lt;span style="line-height: 20px; height: 20px"&gt;本文版权归作者和博客园共有，欢迎转载，但未经作者同意必须保留此段声明。 &lt;/span&gt;&lt;/div&gt;&#xD;
&lt;/div&gt;&lt;img src="http://www.cnblogs.com/Henllyee/aggbug/2007788.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Henllyee/archive/2011/04/07/ParallelProgarmming_Seven_SharingData.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
