<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Ron Jacobs</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/rjacobs/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/rjacobs/feed.xml</link>
    <description>Windows Workflow Foundation</description>
    <lastBuildDate>Mon, 06 Apr 2015 22:26:06 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>My New Role</title>
      <link>https://docs.microsoft.com/archive/blogs/rjacobs/my-new-role</link>
      <pubDate>Sun, 22 Sep 2013 15:49:00 GMT</pubDate>
      <dc:creator><![CDATA[Ron Jacobs]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/rjacobs/2013/09/22/my-new-role/</guid>
      <description><![CDATA[Well after nearly 14 years, 20 countries, dozens of Tech-Ed's, PDC's, and numerous other...]]></description>
      <content:encoded><![CDATA[<p>Well after nearly 14 years, 20 countries, dozens of Tech-Ed's, PDC's, and numerous other &nbsp;events my career at Microsoft is coming to an end. &nbsp;I've made remarkable progress thanks to the generosity of many friends and supporters around the world who helped me with my experimental treatment. &nbsp;This is the treatment that has saved my life</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/28/88/1018.pod.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-28-88/1018.pod.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/28/88/1018.pod.jpg" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-28-88/1018.pod.jpg" alt="" border="0" /></a></p>
<p>The CVAC Pod has given me a measure of health and freedom from pain that I never thought I would experience.</p>
<p>Unfortunately, it is not enough to allow me to return to work. &nbsp;Given my condition with Dercum's Disease, I simply cannot work full time any longer. &nbsp;Microsoft has been nothing short of wonderful to me over these 14 years and especially in the last 2 years as I became more and more sick. &nbsp;It is a great company filled with great people... caring people who do their very best every day to make the &nbsp;world a better place and I am better for having been a part of it.</p>
<p>My new role is President and CEO of the <a href="http://www.dercumsfoundation.org">Dercums Foundation</a>. &nbsp;In this role I am going to do everything I can to make sure that every last person on the face of the earth who suffers from this terrible disease can get access to the treatment that has helped me so much. &nbsp;Today the CVAC pod is not an approved medical device so insurance will not pay for treatments and it is not available outside of the US. &nbsp;I'm going to work as hard as I can to change this situation because for those suffering from Dercum's disease the pain is devastating. &nbsp;You probably won't see me at Tech-Ed or Build any more but I'm around on Facebook and you can always find me at the <a href="http://DercumsFoundation.org">Dercums Foundation</a>. &nbsp;</p>
<p>Thanks for your kindness to me across the years.</p>
<p>Your friend,</p>
<p>Ron Jacobs</p>]]></content:encoded>
    </item>
    <item>
      <title>Status Update</title>
      <link>https://docs.microsoft.com/archive/blogs/rjacobs/status-update</link>
      <pubDate>Wed, 11 Sep 2013 09:16:00 GMT</pubDate>
      <dc:creator><![CDATA[Ron Jacobs]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/rjacobs/2013/09/11/status-update/</guid>
      <description><![CDATA[Thanks to the many supporters and friends who contributed to my first round of&nbsp; fundraising I...]]></description>
      <content:encoded><![CDATA[<p>Thanks to the many supporters and friends who contributed to my <a href="https://www.giveforward.com/fundraiser/trl2/ron-jacobs-dd">first round of&nbsp; fundraising</a> I have been able to start an experiential treatment/therapy to help with my Dercums Disease symptoms.&nbsp; If you are able&nbsp;to contribute to&nbsp;the <a href="https://www.giveforward.com/fundraiser/4yy2/ron-jacobs-dercums-disease-fund-round-2">Ron Jacobs Dercums Disease Fund Round 2</a>, please do I still have a long way to go.&nbsp; This treatment (my word, not the vendors) is not a cure.&nbsp; I will have Dercums Disease for the rest of my life and will have to deal with the pain and trouble that it brings.&nbsp; However, I have improved greatly over the last month and I'm making plans to come back to work.&nbsp;</p>
<p>My old position is no longer available so the first thing I have to do is to find a position.&nbsp; I'm making contacts with friends in Microsoft to try and find something that will work and have some promising leads.&nbsp;I hope to announce something soon.&nbsp; I have to say that Microsoft has been very good to me.&nbsp; I am still a Microsoft employee (on leave) and I am still covered by their medical insurance which is a tremendous help to me.&nbsp; For those of you outside the US you might find that strange but in the US most people get health insurance through their employer.</p>
<p>When I got really sick I moved to California to live with my mother who took care of me (thanks mom!).&nbsp; This weekend I'm heading back to Seattle to find a place to live, meet up with some friends on the Microsoft campus for lunch on Monday, talk with some guys about a possible position and shoot an update for the <a href="https://channel9.msdn.com/shows/This+Week+On+Channel+9/">This Week on Channel 9 show</a>.&nbsp;</p>
<p>Because of my condition, anyone who offers me a position is taking a risk that I might get sick again and be unable to work but I promise you and them (whoever they are) that as long as I am able to sit at a computer and type I will commit myself to producing great samples, great videos and blog posts and to helping you to succeed with whatever you are doing.</p>
<p>Thanks for your support.&nbsp; I'll post an update next week.</p>]]></content:encoded>
    </item>
    <item>
      <title>I will return...</title>
      <link>https://docs.microsoft.com/archive/blogs/rjacobs/i-will-return</link>
      <pubDate>Thu, 22 Aug 2013 16:35:55 GMT</pubDate>
      <dc:creator><![CDATA[Ron Jacobs]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/rjacobs/2013/08/22/i-will-return/</guid>
      <description><![CDATA[Thank you to the many friends who have helped to pay for my experimental treatment with the CVAC...]]></description>
      <content:encoded><![CDATA[<p>Thank you to the many friends who have helped to pay for my experimental treatment with the CVAC machine.&nbsp; I'm so happy to let you know that I'm getting better day by day.&nbsp; In fact, I believe that I will be able to return to work perhaps in the next few months.&nbsp; At this point I don't know exactly what I will be doing when I return but your kindness has given me another chance at life.&nbsp; One way&nbsp;or another... I will return.</p>]]></content:encoded>
    </item>
    <item>
      <title>Another Post...</title>
      <link>https://docs.microsoft.com/archive/blogs/rjacobs/another-post</link>
      <pubDate>Fri, 05 Jul 2013 10:15:00 GMT</pubDate>
      <dc:creator><![CDATA[Ron Jacobs]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/rjacobs/2013/07/05/another-post/</guid>
      <description><![CDATA[I know I said that my previous post was my last post. &nbsp;Today I checked my Microsoft email for...]]></description>
      <content:encoded><![CDATA[<p>I know I said that my <a title="previous post" href="http://blogs.msdn.com/b/rjacobs/archive/2013/01/10/my-last-post.aspx">previous post</a> was my last post. &nbsp;Today I checked my Microsoft email for the first time in a long time and I found several emails from people asking for an update on my condition so here goes...</p>
<h3>It's Worse</h3>
<p>Since I wrote my previous post in January my condition has become much worse. I have now reached the point that I can no longer walk my dog and I rarely leave home. I spend most of my days in severe pain and try to sleep as much as possible because it is the only time I don't feel the pain but even sleep is impossible without medication.</p>
<h3>But there's new hope</h3>
<p>I recently learned about a new experimental treatment for Dercums Disease. Unfortunately, this treatment is not covered by insurance so I've started a fundraiser to get the money I need to pay for this treatment. I've spoken with 2 people who had this disease and have recovered wonderfully after treatments with a CVAC machine. If you want to donate or learn more just click on the right and thanks for your support</p>]]></content:encoded>
    </item>
    <item>
      <title>My Last Post</title>
      <link>https://docs.microsoft.com/archive/blogs/rjacobs/my-last-post</link>
      <pubDate>Thu, 10 Jan 2013 08:49:27 GMT</pubDate>
      <dc:creator><![CDATA[Ron Jacobs]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/rjacobs/2013/01/10/my-last-post/</guid>
      <description><![CDATA[A few months ago I wrote this post about my diagnosis with Adiposis Dolorosa (Dercum's Disease)....]]></description>
      <content:encoded><![CDATA[<p>A few months ago I wrote <a href="http://blogs.msdn.com/b/rjacobs/archive/2012/07/09/what-s-up-with-ron.aspx">this post</a> about my diagnosis with <a href="http://en.wikipedia.org/wiki/Adiposis_dolorosa">Adiposis Dolorosa (Dercum's Disease)</a>. After writing it I had a brief reprieve from the symptoms and for a while I was able to work part time.&nbsp; Then in September I had surgery to remove some of the tumors.&nbsp; For some unknown reason this caused the disease to progress rapidly.&nbsp; I have now reached the point where I can no longer work at all.&nbsp; Not only that, I cannot even live on my own and take care of myself.&nbsp; I have had to move in with my mother so she can take care of me.&nbsp; I miss my work terribly and I see email from many of you asking questions about this or that but I am unable to answer them.</p>
<p>As for the future, no one really knows what this disease will do to me in the long run.&nbsp; The doctors have been very surprised to see this devastating impact so quickly.&nbsp; Not only is this disease causing a great deal of pain, it is also attacking my brain making it very difficult to do even simple tasks.</p>
<p>Over the years I have seen farewell blog posts from many of my colleagues at Microsoft.&nbsp; Most are moving on to bigger and better things.&nbsp; I wish this was the case for me.&nbsp; Unfortunately it is not.</p>]]></content:encoded>
    </item>
    <item>
      <title>The Amazing Race</title>
      <link>https://docs.microsoft.com/archive/blogs/rjacobs/the-amazing-race</link>
      <pubDate>Wed, 05 Sep 2012 12:09:50 GMT</pubDate>
      <dc:creator><![CDATA[Ron Jacobs]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/rjacobs/2012/09/05/the-amazing-race/</guid>
      <description><![CDATA[I’ll never forget the first time I heard someone mention a “Race Condition”.&#160; In my younger...]]></description>
      <content:encoded><![CDATA[<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/28/88/metablogapi/7737.MP900424397_66161171.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-28-88-metablogapi/7737.MP900424397_5F00_66161171.jpg"><img title="MP900424397" style="display: inline; background-image: none;" border="0" alt="MP900424397" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/28/88/metablogapi/8726.MP900424397_thumb_1A4A3AB8.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-28-88-metablogapi/8726.MP900424397_5F00_thumb_5F00_1A4A3AB8.jpg" width="244" height="164" /></a></p>  <p>I’ll never forget the first time I heard someone mention a “Race Condition”.&#160; In my younger years when I was more worried about what people thought of me I was to embarrassed to admit that I didn’t really know what they were talking about.&#160; I knew it had something to do with multi-threaded programs and the unpredictability of order and locking and blah, blah, blah…&#160; To be honest it seemed like so much noise to me at the time.&#160; After all, most of the programs I wrote never had to contend with this.</p>  <h3>But Then…</h3>  <p>Then when multi-core hyper-threaded systems became common place and I started working on Windows Workflow Foundation and dealing with multiple threads and race conditions became unavoidable.&#160; My current computer is an Intel I7 6 Core hyper-threaded system which means that in Windows Task manager it shows 12 CPUs.&#160; When I started using <a href="http://ncrunch.net">NCrunch</a> to run my unit tests in parallel I found many threading bugs and race conditions in my code.</p>  <h3>Why is this so difficult?</h3>  <blockquote>   <p><em>“With great power, comes great responsibility” – Spiderman</em></p> </blockquote>  <p>It just is… What can you say? Let’s just agree that your life would be simpler if you always use a request per thread model and avoid access to shared state.&#160; You can do a lot with this type of programming but then one day you will have to cross that line and when you do… don’t hurt yourself.</p>  <h3>Why is this a race?</h3>  <p>Imagine each of the runners in the picture above is a CPU Core.&#160; Each of them is working all at once.&#160; If they don’t interfere with each other or depend on each other then no problem but what if…</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/28/88/metablogapi/1070.MP900424394_6F05A3B0.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-28-88-metablogapi/1070.MP900424394_5F00_6F05A3B0.jpg"><img title="MP900424394" style="display: inline; background-image: none;" border="0" alt="MP900424394" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/28/88/metablogapi/8836.MP900424394_thumb_40AC1E03.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-28-88-metablogapi/8836.MP900424394_5F00_thumb_5F00_40AC1E03.jpg" width="244" height="164" /></a></p>  <p>What if one runner has to wait for another runner to hand off some data before it can continue?&#160; Now you have to coordinate this race.&#160; There are two ways to do this, locking and waiting.&#160; <a href="http://www.wintellect.com/cs/blogs/jeffreyr/">Jeff Richter</a> taught me that waiting is better than locking.&#160; In fact, the best designs avoid locks entirely.&#160; </p>  <p>Imagine a relay race where the runners approach the stadium to find a guard there who will allow one and only one runner on the track at a time.&#160; Each runner, enters the stadium, runs their leg of the race, exits the stadium and then the other runner is allowed to enter.&#160; Sure, it works but there are problems… performance, deadlocks, live locks, recursion and others that I won’t get into here.</p>  <p>Now imagine that all runners enter the stadium, each takes their place and then the race begins.&#160; Our relay team has only one runner active and the others… wait.&#160; They wait until a signal (in this case the baton) tells them that the other thread is done and they can now begin.</p>  <p>Fine but… what if there were three runners and three batons and our runner must begin when one of two of the three complete and if the other one completes the race is over with a disqualification?</p>  <h3>Outcomes</h3>  <p>Where you will get into trouble is when you assume that you know the outcome of a race.&#160; You may notice that when you run your program in the debugger that the race always ends up in the order [a, b, c].&#160; So you ship your program only to find that once in a while a customer reports an error that can only occur when the order is [c, a, b].&#160; How can this be?&#160; You setup a test environment and run the program a million times and it never does [c, a, b] so you close the bug as “not repro”.&#160; But is the customer just crazy?&#160; Or unlucky?&#160; Or did you create a program that has a threading bug because of a race condition?</p>  <p>In a race, there are only three possible outcomes </p>  <ol>   <li>None</li>    <li>All</li>    <li>Any</li> </ol>  <p>Given a point in time <em><strong>t</strong></em></p>  <ul>   <li><strong>None</strong> – none of the racers have completed the race</li>    <li><strong>All</strong> – all have completed the race</li>    <li><strong>Any</strong> – some have completed the race</li> </ul>  <p>If you make any other assumption about the order of the race participants you will be wrong sooner or later.&#160; </p>  <h3>So What?</h3>  <p>As I’m currently thinking about API design, I’m asking this question.</p>  <blockquote>   <p><em><strong>“Can I make Windows Workflow Foundation easier to use?”</strong></em></p> </blockquote>  <p>One reason that it is difficult is that we have created a race and asked you to solve it.&#160; Any time you run a workflow, you are engaging in multi-threaded programming.&#160; You found this out the first time you called WorkflowApplication.Run() only to find that Run just starts the workflow.&#160; </p>  <p>How do you know when the workflow is done?&#160; Well that depends… </p>  <p>Imagine that there is a race</p>  <ul>   <li>In lane 1 – Idle</li>    <li>In lane 2 – Faulted</li>    <li>In lane 3 – Completed</li>    <li>In lane 4 – Canceled</li> </ul>  <p>Run is like the starting pistol.&#160; Now you have to wait for the outcome of the race.&#160; You have to write some complicated code to take into account the possible outcomes, code which most developers have never written previously.</p>  <p>I’d like to propose that the solution to making this easier is to use a Task to represent some of the runners in our race and exceptions to represent others.&#160; For example, we can assume that typical outcomes would be Idle or Completed and that exceptional outcomes would be Faulted and Canceled.&#160; Once we have taken that step Task has some helpful methods.</p>  <ul>   <li>If I want a task that will complete when the workflow becomes idle or completes I can call Task.WhenAny(idleTask, completedTask)</li>    <li>If I want to wait with a timeout I can call Task.WaitAll() or Task.WaitAny()</li> </ul>  <p>Now instead of pushing the problem of waiting onto you, Workflow can give you tools that make it easy to do the right thing.</p>  <p>Once again, let me say I’m thinking out loud here.&#160; This is not a promise, just a dream for now…</p>  <p>Happy Coding   <br />Ron Jacobs    <br /><a href="http://blogs.msdn.com/rjacobs">http://blogs.msdn.com/rjacobs</a>    <br />Twitter: <a href="https://twitter.com/ronljacobs">@ronljacobs</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Less is More</title>
      <link>https://docs.microsoft.com/archive/blogs/rjacobs/less-is-more</link>
      <pubDate>Wed, 22 Aug 2012 10:28:18 GMT</pubDate>
      <dc:creator><![CDATA[Ron Jacobs]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/rjacobs/2012/08/22/less-is-more/</guid>
      <description><![CDATA[I am a musician. Over the years I have played keyboards in many bands, traveling and performing...]]></description>
      <content:encoded><![CDATA[<p><a href="http://upload.wikimedia.org/wikipedia/commons/b/ba/Tonysmith_freeride_sculpture.jpg"><img alt="File:Tonysmith freeride sculpture.jpg" src="http://upload.wikimedia.org/wikipedia/commons/b/ba/Tonysmith_freeride_sculpture.jpg" width="400" height="249" /></a></p>  <p>I am a musician. Over the years I have played keyboards in many bands, traveling and performing mostly as a hobby. I’ll never forget what one of my mentors taught me. He said</p>  <blockquote>   <p>“The rest is just as important as the note”</p> </blockquote>  <p>The rest is the part of the song where you don’t play. Young musicians often forget this and take great delight in trying to dazzle you with their dexterity. Put a group of young musicians together and you get a cacophony of noise. The purpose, the beauty, the soul of the music is lost in the means of its production.</p>  <p>When I enter a planning process in building software, I want to keep this principle in mind. The things I leave out are just as important as the things I put in. </p>  <h3>What Problem Are We Solving?</h3>  <p>Unlike music or art which can exist simply for their beauty, software is utilitarian. It is a tool and no tool ever existed without a problem that it seeks to solve. The first step in building a great tool is to be very clear about the problem.</p>  <ul>   <li>What is the problem?</li>    <li>Who has this problem?</li>    <li>When does this problem occur?</li>    <li>What would make it better?</li> </ul>  <h3>Why This Matters</h3>  <blockquote>   <p>“Well those drifter's days are past me now      <br />I've got so much more to think about       <br />Deadlines and commitments       <br />What to leave in, what to leave out”</p>    <p>- Bob Seger – “Against the Wind”</p> </blockquote>  <p>The art of building great software begins with the art of making great choices. We can’t do everything… we need to do the best thing that we can with the time we’ve and resources we’ve got.</p>  <h3>Taking a Risk</h3>  <p>Right now I’m still in the stage of defining it but I’m going to be as transparent as possible with you in this process with the hope that you can give me feedback. There is some risk in this. You might disagree with my conclusions. You might wonder about the priorities that we have as a team. You might get the wrong impression… blah, blah, blah…</p>  <p>We live in a time of increasing secrecy in the tech industry. Companies take delight in hiding the details and then in one dramatic moment pulling back the curtain to a round of applause. I suppose that for some things that is the best approach, but you and I are in a different place. We need each other and we need to be transparent which means we run the risk of misunderstanding and that’s ok. </p>  <h3>What Problem is Ron Solving?</h3>  <p>I’ve been given the job of making Workflow and System.Threading.Task work well together. I began by researching the situation as it exists today. I might have come to conclusion that there is no problem or that even if there is a problem that it is so small it’s not worth addressing. Or I could have concluded that the problem is so massive that nothing can be done about it. I came to my initial conclusions by talking with some of you, my own experience and many hours prototyping and trying to work with tasks and workflows together.</p>  <h4>What is the problem?</h4>  <p>There are two key problems and one opportunity.</p>  <ol>   <li><strong>Problem:</strong> Windows Workflow Foundation (WF) has a large API surface composed of three key classes (WorkflowInvoker, WorkflowApplication and WorkflowServiceHost) none of which is Task enabled as defined by the <a href="http://www.microsoft.com/en-us/download/details.aspx?id=19957">Task Asynchronous Pattern</a>.       <br /></li>    <li><strong>Problem:</strong> Developers who want to implement the Task Asynchronous Pattern in their hosting code and activity code will find it difficult if not impossible to do so.       <br /></li>    <li><strong>Opportunity:</strong> Because we have to introduce new API surface to solve these problems we may be able to at the same time make learning and using Workflow both easier and more powerful if we are very careful.</li> </ol>    <h3>Problem: WF does not implement the Task Asynchronous Pattern (TAP)</h3>  <p>Here are a few examples</p>  <table cellspacing="0" cellpadding="2" width="100%" border="0"><tbody>     <tr>       <td valign="top" width="50%"><strong>Task Async Pattern</strong></td>        <td valign="top" width="50%"><strong>Workflow</strong></td>     </tr>      <tr>       <td valign="top" width="50%">Async methods should end with the “Async” suffix </td>        <td valign="top" width="50%">WorkflowApplication.Run() is async</td>     </tr>      <tr>       <td valign="top" width="50%">Async methods should return a Task so the caller can call Task.Wait() </td>        <td valign="top" width="50%">Async methods return void </td>     </tr>      <tr>       <td valign="top" width="50%">Result accessed with Task<t>.Result </t></td>        <td valign="top" width="50%">Caller must implement delegates and wait handles to wait and access result </td>     </tr>      <tr>       <td valign="top" width="50%">Exceptions in task are marshaled to calling thread in an AggregateException </td>        <td valign="top" width="50%">Exceptions in Activities are handled by the Aborted delegate or the Completed delegate depending on the UnhandledExceptionAction of the host </td>     </tr>      <tr>       <td valign="top" width="50%">Tasks are canceled by calling CancellationTokenSource.Cancel() which signals a CancellationToken that is passed to child tasks. </td>        <td valign="top" width="50%">Activities are canceled by WorkflowAppliication.Cancel or NativeActivityContext.CancelChild / CancelChildren </td>     </tr>   </tbody></table>  <p>As more and more developers become familiar with System.Threading.Task and the way it works with other classes in the .NET Framework they will expect that Workflow works the same way. If it did work the same way then someone who is familiar with Task will find Workflow more familiar.</p>  <h3>Problem: Implementing TAP With Activities</h3>  <p>Suppose you want to create an activity that access a database and you want to use SqlConnection.OpenAsync(cancellationToken). This new API is great because if the database server is down, you can cancel the Open operation on demand. Your first challenge is how to pass a CancellationToken from your workflow hosting code to the database activity. You could pass it as an in argument and require workflow authors to pass it to your activity but that doesn’t seem like the right approach. </p>  <p>So instead, you decide to pass it as an extension only to find that when you call workflowApp.Extensions.Add(cancellationToken) that you get an error stating that extensions must be reference types. No problem, you create a class that allows you to pass the token as an extension to the activity.</p>  <p>Now you’ve got it right? So you create a unit test to verify that if you try to connect to a server that does not exist and then cancel the token using CancellationTokenSource.Cancel that the activity immediately cancels the OpenAsync call and returns.</p>  <p>At first you think it works but then you notice that your workflow terminates with a TerminationException of AggregateException –&gt; OperationCanceledException.</p>  <p>Is that ok? Should a cancel cause a workflow to terminate?</p>  <p>No, it should not. Workflow already has a model for cancellation of activities. Someone may use your database activity inside of a CancellationScope. If your activity faults when it is really just canceled then the cancellation handler will not be invoked.</p>  <p>This is just one of several problems I’ve identified with using tasks inside of activities.</p>  <h3>Opportunity: Make Workflow Easier and More Powerful</h3>  <p>Any time you change an existing API there are both risks and opportunities. We could try to make it better, simpler and more powerful and actually end up making it worse, more complicated or break existing things. We must be very careful about how we approach this opportunity.</p>  <p>When it comes to workflows and tasks here are my design principles.</p>  <ol>   <li>Embrace, don’t try to hide the asynchronous nature of Workflow</li>    <ul>     <li>When a caller wants to wait for something to happen with a workflow (complete, idle, load, unload, cancel etc. etc.) they should receive a task that allows them to wait for that thing.</li>   </ul>    <li>A caller may create 0..n tasks when using Workflow</li>    <ul>     <li>Users may “Fire and Forget” a workflow (0 tasks)</li>      <li>Users may want to create a task to wait for a workflow to become idle in addition to a task to wait for the workflow to complete (2 tasks)        <br /></li>   </ul>    <li>If a caller has requested a task to wait for a specific event (idle, complete, unload, etc.) and the event that they received it for </li>    <ul>     <li>Did happen the task will complete. </li>      <li>Did not happen yet but still could happen within the lifetime of the AppDomain, the task will remain running</li>      <li>Did not happen yet and will never happen within the lifetime of the AppDomain the task will be canceled.        <br /></li>   </ul>    <li>If the workflow faults then</li>    <ul>     <li>The main task will be faulted, all others will cancel</li>   </ul> </ol>  <p>Ok, ready for the risk disclaimer?</p>  <p>None of this might happen. Or what eventually happens might be radically different than what I am thinking right now. Blogs live forever so if you come back in 5 years and read this you might laugh… but that is a risk I’m willing to take.</p>    <p>Happy Coding!</p>  <p>Ron    <br /><a href="http://blogs.msdn.com/rjacobs">http://blogs.msdn.com/rjacobs</a>     <br />Twitter: <a href="https://twitter.com/ronljacobs">@ronljacobs</a></p>]]></content:encoded>
    </item>
    <item>
      <title>How to use LINQ in a Workflow</title>
      <link>https://docs.microsoft.com/archive/blogs/rjacobs/how-to-use-linq-in-a-workflow</link>
      <pubDate>Fri, 27 Jul 2012 09:32:40 GMT</pubDate>
      <dc:creator><![CDATA[Ron Jacobs]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/rjacobs/2012/07/27/how-to-use-linq-in-a-workflow/</guid>
      <description><![CDATA[Question  Can I use a LINQ Query such as the following in a Workflow?     private static void...]]></description>
      <content:encoded><![CDATA[<h3>Question</h3>  <p>Can I use a LINQ Query such as the following in a Workflow?</p>  <div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: &quot;Consolas&quot;, consolas, monospace; font-size: 8pt; cursor: text; direction: ltr; max-height: 200px; background-color: rgb(244, 244, 244);">   <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Consolas&quot;, consolas, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><p><span style="color: rgb(0, 0, 255);">private</span> <span style="color: rgb(0, 0, 255);">static</span> <span style="color: rgb(0, 0, 255);">void</span> ShowQueryWithCode(IEnumerable&lt;<span style="color: rgb(0, 0, 255);">string</span>&gt; names)<br />{<br />    Console.WriteLine(<span style="color: rgb(0, 96, 128);">&quot;Linq Query in Code - show names that start with 'R'&quot;</span>);<br /><br />    <span style="color: rgb(0, 128, 0);">// Assuming there are no null entries in the names collection</span><br />    var query = from name <span style="color: rgb(0, 0, 255);">in</span> names <span style="color: rgb(0, 0, 255);">where</span> name.StartsWith(<span style="color: rgb(0, 96, 128);">&quot;R&quot;</span>) select name;<br /><br />    <span style="color: rgb(0, 128, 0);">// This is the same thing as </span><br />    <span style="color: rgb(0, 128, 0);">// var query = names.Where(name =&gt; name.StartsWith(&quot;R&quot;));</span></p><p><span style="color: rgb(0, 128, 0);"></span><font color="#008000"></font><br />    <span style="color: rgb(0, 0, 255);">foreach</span> (var name <span style="color: rgb(0, 0, 255);">in</span> query)<br />    {<br />        Console.WriteLine(name);<br />    }<br /><br />    Console.WriteLine();<br />}<br /></p></pre>

  <br /></div>

<h2 class="scriptcode">
  <div class="pluginEditHolder" plugincommand="mceScriptCode">
    <div class="title">Answer</div>
  </div>
</h2>

<p>Yes, you can use LINQ with a Workflow in exactly the same way.</p>

<h3><a href="http://code.msdn.microsoft.com/Using-Linq-Queries-in-5b17f6be">Download Sample Code</a></h3>

<p>&#160;</p>

<h3>Step 1: Create a Workflow with an In Argument of type IEnumerable&lt;string&gt;</h3>

<p>Here you can see that I've added the in argument</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/28/88/metablogapi/7450.argument_50C13C9E.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-28-88-metablogapi/7450.argument_5F00_50C13C9E.png"><img title="argument" style="border: 0px currentcolor; display: inline; background-image: none;" border="0" alt="argument" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/28/88/metablogapi/5315.argument_thumb_30A62FE1.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-28-88-metablogapi/5315.argument_5F00_thumb_5F00_30A62FE1.png" width="517" height="85" /></a></p>

<h3>Step 2: Add a Variable for the query of type IEnumerable&lt;string&gt;</h3>

<p>Before you can add a variable you need to include an activity which has variables.&#160; In this workflow I've added a sequence.</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/28/88/metablogapi/4338.variable_3E7875DC.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-28-88-metablogapi/4338.variable_5F00_3E7875DC.png"><img title="variable" style="border: 0px currentcolor; display: inline; background-image: none;" border="0" alt="variable" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/28/88/metablogapi/5808.variable_thumb_37593964.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-28-88-metablogapi/5808.variable_5F00_thumb_5F00_37593964.png" width="471" height="85" /></a></p>

<h3>Step 3: Assign the query the LINQ expression you want to use</h3>

<p>You can use a method chain or query syntax.</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/28/88/metablogapi/6560.expression_173E2CA7.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-28-88-metablogapi/6560.expression_5F00_173E2CA7.png"><img title="expression" style="border: 0px currentcolor; display: inline; background-image: none;" border="0" alt="expression" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/28/88/metablogapi/7140.expression_thumb_101EF02F.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-28-88-metablogapi/7140.expression_5F00_thumb_5F00_101EF02F.png" width="638" height="183" /></a></p>

<h3>Step 4: Iterate over the collection</h3>

<p>In the completed workflow I used a ForEach&lt;string&gt; activity to iterate the list of names and write them to the console.</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/28/88/metablogapi/2843.Workflow1_1DF1362A.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-28-88-metablogapi/2843.Workflow1_5F00_1DF1362A.jpg"><img title="Workflow1" style="border: 0px currentcolor; display: inline; background-image: none;" border="0" alt="Workflow1" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/28/88/metablogapi/8032.Workflow1_thumb_5DBB1CAF.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-28-88-metablogapi/8032.Workflow1_5F00_thumb_5F00_5DBB1CAF.jpg" width="339" height="610" /></a></p>

<h3>Summary</h3>

<p>This example uses C# in .NET 4.5 but the same technique can be used with Visual Basic.</p>

<p>When you run it you can see that both methods work the same.</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/28/88/metablogapi/2678.console_218F5107.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-28-88-metablogapi/2678.console_5F00_218F5107.png"><img title="console" style="border: 0px currentcolor; display: inline; background-image: none;" border="0" alt="console" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/28/88/metablogapi/6064.console_thumb_5D4EE9BA.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-28-88-metablogapi/6064.console_5F00_thumb_5F00_5D4EE9BA.png" width="240" height="83" /></a></p>

<p>Happy Coding!</p>

<p>Ron Jacobs
  <br /><a href="http://blogs.msdn.com/rjacobs">http://blogs.msdn.com/rjacobs</a>

  <br /> Twitter: <a href="https://twitter.com/ronljacobs">@ronljacobs</a></p>]]></content:encoded>
    </item>
    <item>
      <title>How to make a library portable and data binding friendly at the same time?</title>
      <link>https://docs.microsoft.com/archive/blogs/rjacobs/how-to-make-a-library-portable-and-data-binding-friendly-at-the-same-time</link>
      <pubDate>Sun, 22 Jul 2012 11:03:10 GMT</pubDate>
      <dc:creator><![CDATA[Ron Jacobs]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/rjacobs/2012/07/22/how-to-make-a-library-portable-and-data-binding-friendly-at-the-same-time/</guid>
      <description><![CDATA[Here is the challenge.&#160;      Create a portable library that could be used by almost anything...]]></description>
      <content:encoded><![CDATA[<p>Here is the challenge.&#160; </p>  <ol>   <li>Create a portable library that could be used by almost anything including Console Apps, Windows Phone, ASP.NET, Xbox 360 </li>    <li>Make it data binding friendly for targets like WPF, Silverlight and Windows 8 XAML Metro Apps by supporting property and collection changed notifications.</li>    <li>Make it efficient so that users who don’t need data binding are not penalized with a performance hit and having to reference libraries they don’t need.</li>    <li>Write Unit Tests to demonstrate that the solution works for both data binding and non-data binding users.</li> </ol>  <p>I was a little stumped so I decided to ask about this on StackOverflow see <a title="C# Class library collections ObservableCollection T vs Collection T" href="http://stackoverflow.com/questions/11600952/c-sharp-class-library-collections-observablecollectiont-vs-collectiont">C# Class library collections ObservableCollection T vs Collection T</a> and based on what the community came up with, here is my solution – can you do better?</p>  <p><a href="http://code.msdn.microsoft.com/How-to-make-a-library-c8d42316"><strong>Download Sample Code</strong></a></p>  <h3>The Base Class: Foo</h3>  <p>If you don’t want data binding, Foo is for you.&#160; It is a simple class.&#160; It has a property “Num” and a collection “Strings” with a method called Populate().&#160; You’ll notice that I created some virtual members to allow the derived class to do what it needs to do.</p>  <div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: &quot;Consolas&quot;, consolas, monospace; font-size: 8pt; cursor: text; direction: ltr; max-height: 200px; background-color: rgb(244, 244, 244);">   <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Consolas&quot;, consolas, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">class</span> Foo<br />{<br />    <span style="color: rgb(0, 0, 255);">private</span> <span style="color: rgb(0, 0, 255);">readonly</span> Collection&lt;<span style="color: rgb(0, 0, 255);">string</span>&gt; strings = <span style="color: rgb(0, 0, 255);">new</span> Collection&lt;<span style="color: rgb(0, 0, 255);">string</span>&gt;();<br /><br />    <span style="color: rgb(0, 128, 0);">/// &lt;summary&gt;</span><br />    <span style="color: rgb(0, 128, 0);">/// Gets the Num value</span><br />    <span style="color: rgb(0, 128, 0);">/// &lt;/summary&gt;</span><br />    <span style="color: rgb(0, 128, 0);">/// &lt;remarks&gt;</span><br />    <span style="color: rgb(0, 128, 0);">/// This property is virtual so that the derived Observable class can provide property changed notifications</span><br />    <span style="color: rgb(0, 128, 0);">/// &lt;/remarks&gt;</span><br />    <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">virtual</span> <span style="color: rgb(0, 0, 255);">int</span> Num { get; set; }<br /><br />    <span style="color: rgb(0, 128, 0);">/// &lt;summary&gt;</span><br />    <span style="color: rgb(0, 128, 0);">/// Gets the collection of strings</span><br />    <span style="color: rgb(0, 128, 0);">/// &lt;/summary&gt;</span><br />    <span style="color: rgb(0, 0, 255);">public</span> ReadOnlyCollection&lt;<span style="color: rgb(0, 0, 255);">string</span>&gt; Strings<br />    {<br />        get<br />        {<br />            <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">new</span> ReadOnlyCollection&lt;<span style="color: rgb(0, 0, 255);">string</span>&gt;(<span style="color: rgb(0, 0, 255);">this</span>.strings);<br />        }<br />    }<br /><br />    <span style="color: rgb(0, 128, 0);">/// &lt;summary&gt;</span><br />    <span style="color: rgb(0, 128, 0);">/// The collection of strings</span><br />    <span style="color: rgb(0, 128, 0);">/// &lt;/summary&gt;</span><br />    <span style="color: rgb(0, 128, 0);">/// &lt;remarks&gt;</span><br />    <span style="color: rgb(0, 128, 0);">/// This property is protected virtual so that the Observable class can substitue an</span><br />    <span style="color: rgb(0, 128, 0);">/// ObservableCollection </span><br />    <span style="color: rgb(0, 128, 0);">/// &lt;/remarks&gt;</span><br />    <span style="color: rgb(0, 0, 255);">protected</span> <span style="color: rgb(0, 0, 255);">virtual</span> ICollection&lt;<span style="color: rgb(0, 0, 255);">string</span>&gt; StringsCollection<br />    {<br />        get<br />        {<br />            <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">this</span>.strings;<br />        }<br />    }<br /><br />    <span style="color: rgb(0, 128, 0);">/// &lt;summary&gt;</span><br />    <span style="color: rgb(0, 128, 0);">/// Populates the string collection</span><br />    <span style="color: rgb(0, 128, 0);">/// &lt;/summary&gt;</span><br />    <span style="color: rgb(0, 128, 0);">/// &lt;param name=&quot;max&quot;&gt;The maximum size for the collection&lt;/param&gt;</span><br />    <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">void</span> Populate(<span style="color: rgb(0, 0, 255);">int</span> max = 1000)<br />    {<br />        <span style="color: rgb(0, 128, 0);">// If no num was specified, create a random value</span><br />        <span style="color: rgb(0, 0, 255);">if</span> (Num == 0)<br />        {<br />            var r = <span style="color: rgb(0, 0, 255);">new</span> Random();<br />            <span style="color: rgb(0, 0, 255);">this</span>.Num = r.Next(1, max);<br />        }<br /><br />        <span style="color: rgb(0, 0, 255);">if</span> (Num &gt; max)<br />        {<br />            <span style="color: rgb(0, 0, 255);">throw</span> <span style="color: rgb(0, 0, 255);">new</span> InvalidOperationException(<span style="color: rgb(0, 96, 128);">&quot;Num is greater than max&quot;</span>);<br />        }<br /><br />        <span style="color: rgb(0, 0, 255);">for</span> (var i = 0; i &lt; <span style="color: rgb(0, 0, 255);">this</span>.Num; i++)<br />        {<br />            <span style="color: rgb(0, 0, 255);">this</span>.StringsCollection.Add(<span style="color: rgb(0, 0, 255);">string</span>.Format(<span style="color: rgb(0, 96, 128);">&quot;string {0}&quot;</span>, i));<br />        }<br />    }<br />}<br /></pre>

  <br /></div>

<h3>The Derived Class: ObservableFoo</h3>

<p><strong>ObservableFoo</strong> is just like <strong>Foo</strong> except that it is data binding ready because it supports <a href="http://msdn.microsoft.com/en-us/library/ms133020(v=vs.110)">INotifyPropertyChanged</a> and uses an <a href="http://msdn.microsoft.com/en-us/library/ms668604(v=vs.110)">ObservableCollection&lt;string&gt;</a> to do it’s work.&#160; The first thing <strong>ObservableFoo</strong> must do is to get the base class <strong>Foo</strong> to use an <a href="http://msdn.microsoft.com/en-us/library/ms668604(v=vs.110)">ObservableCollection&lt;string&gt;</a> so it overrides the <strong>StringCollection</strong> property.</p>

<p>Second, <strong>Foo.Strings</strong> is a <a href="http://msdn.microsoft.com/en-us/library/ms132474(v=vs.110)">ReadOnlyCollection&lt;string&gt;</a> which won’t do for data binding.&#160; Instead we need to return a&#160; data binding friendly <a href="http://msdn.microsoft.com/en-us/library/ms668620(v=vs.110)">ReadOnlyObservableCollection&lt;string&gt;</a>. To do this I hide the <strong>Foo.Strings</strong> property with the <a href="http://msdn.microsoft.com/en-us/library/435f1dw2(v=vs.110)">new modifier</a>.</p>

<p>Third, I override the <strong>Num</strong> property so I can fire a <a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.propertychanged(v=vs.110)">PropertyChanged</a> notification when it is set.</p>

<p>Finally, I place <strong>ObservableFoo</strong> into a different assembly named <strong>FooLibrary.Observable</strong> since this project must reference <strong>System.Windows</strong> and forces all those who use it to do the same.</p>

<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: &quot;Consolas&quot;, consolas, monospace; font-size: 8pt; cursor: text; direction: ltr; max-height: 200px; background-color: rgb(244, 244, 244);">
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Consolas&quot;, consolas, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">sealed</span> <span style="color: rgb(0, 0, 255);">class</span> ObservableFoo : Foo, INotifyPropertyChanged<br />{<br />    <span style="color: rgb(0, 0, 255);">private</span> <span style="color: rgb(0, 0, 255);">readonly</span> ObservableCollection&lt;<span style="color: rgb(0, 0, 255);">string</span>&gt; strings = <span style="color: rgb(0, 0, 255);">new</span> ObservableCollection&lt;<span style="color: rgb(0, 0, 255);">string</span>&gt;();<br /><br />    <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">event</span> PropertyChangedEventHandler PropertyChanged;<br /><br />    <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">override</span> <span style="color: rgb(0, 0, 255);">int</span> Num<br />    {<br />        get<br />        {<br />            <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">base</span>.Num;<br />        }<br />        set<br />        {<br />            <span style="color: rgb(0, 0, 255);">base</span>.Num = <span style="color: rgb(0, 0, 255);">value</span>;<br />            <span style="color: rgb(0, 0, 255);">this</span>.OnPropertyChanged(<span style="color: rgb(0, 96, 128);">&quot;Num&quot;</span>);<br />        }<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">new</span> ReadOnlyObservableCollection&lt;<span style="color: rgb(0, 0, 255);">string</span>&gt; Strings<br />    {<br />        get<br />        {<br />            <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">new</span> ReadOnlyObservableCollection&lt;<span style="color: rgb(0, 0, 255);">string</span>&gt;(<span style="color: rgb(0, 0, 255);">this</span>.strings);<br />        }<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">protected</span> <span style="color: rgb(0, 0, 255);">override</span> ICollection&lt;<span style="color: rgb(0, 0, 255);">string</span>&gt; StringsCollection<br />    {<br />        get<br />        {<br />            <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">this</span>.strings;<br />        }<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">private</span> <span style="color: rgb(0, 0, 255);">void</span> OnPropertyChanged(<span style="color: rgb(0, 0, 255);">string</span> propertyName)<br />    {<br />        var handler = <span style="color: rgb(0, 0, 255);">this</span>.PropertyChanged;<br />        <span style="color: rgb(0, 0, 255);">if</span> (handler != <span style="color: rgb(0, 0, 255);">null</span>)<br />        {<br />            handler(<span style="color: rgb(0, 0, 255);">this</span>, <span style="color: rgb(0, 0, 255);">new</span> PropertyChangedEventArgs(propertyName));<br />        }<br />    }<br />}<br /></pre>

  <br /></div>

<h3>The Unit Tests</h3>

<p>Testing <strong>Foo</strong> is pretty straight forward so I won't go into detail about that here, but testing <strong>ObservableFoo</strong> was quite interesting.&#160; I have found that in most projects with Model / View / View Model (MVVM) that people neglect to test property change notifications.&#160; Then you get subtle bugs in the UI because the property change notifications are not firing as expected.&#160; I wanted to create a test that would verify that <strong>ObservableFoo</strong> was indeed observable so I created the <strong>FooObserver</strong>.&#160; First a test that uses it.</p>

<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: &quot;Consolas&quot;, consolas, monospace; font-size: 8pt; cursor: text; direction: ltr; max-height: 200px; background-color: rgb(244, 244, 244);">
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Consolas&quot;, consolas, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 128, 0);">/// &lt;summary&gt;</span><br /><span style="color: rgb(0, 128, 0);">/// Given</span><br /><span style="color: rgb(0, 128, 0);">/// * An ObservableFoo</span><br /><span style="color: rgb(0, 128, 0);">/// When</span><br /><span style="color: rgb(0, 128, 0);">/// * Populated</span><br /><span style="color: rgb(0, 128, 0);">/// Then</span><br /><span style="color: rgb(0, 128, 0);">/// * The number of CollectionChangedNotifications is equal to Num</span><br /><span style="color: rgb(0, 128, 0);">/// * The number of PropertyChangedNotifications is equal to Num * 2</span><br /><span style="color: rgb(0, 128, 0);">/// &lt;/summary&gt;</span><br />[TestMethod]<br /><span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">void</span> ObservableFooRaisesChangeNotificationsWhenPopulated()<br />{<br />    <span style="color: rgb(0, 128, 0);">// Arrange</span><br />    <span style="color: rgb(0, 0, 255);">const</span> <span style="color: rgb(0, 0, 255);">int</span> Expected = 100;<br />    <span style="color: rgb(0, 0, 255);">const</span> <span style="color: rgb(0, 0, 255);">int</span> ExpectedPropNotifications = Expected * 2;<br /><br />    var foo = <span style="color: rgb(0, 0, 255);">new</span> ObservableFoo() { Num = Expected };<br /><br />    <span style="color: rgb(0, 128, 0);">// Create an observer to monitor the notifications</span><br />    var observer = <span style="color: rgb(0, 0, 255);">new</span> FooObserver(foo);<br /><br />    <span style="color: rgb(0, 128, 0);">// Act</span><br />    foo.Populate();<br /><br />    <span style="color: rgb(0, 128, 0);">// Assert</span><br />    <span style="color: rgb(0, 128, 0);">// Each item that was added to the collection should trigger a CollectionChangedNotification</span><br />    Assert.AreEqual(Expected, observer.CollectionChangedNotifications.Count);<br /><br />    <span style="color: rgb(0, 128, 0);">// Each time an item is added 2 property changed notifications are raised</span><br />    <span style="color: rgb(0, 128, 0);">// Count and Item[]</span><br />    Assert.AreEqual(ExpectedPropNotifications, observer.PropertyChangedNotifications.Count);<br />}<br /></pre>

  <br /></div>

<p>Here you can see that my observer simply attaches itself to the ObservableFoo and captures the notifications received so I can assert them.&#160; The implementation is not too difficult but interesting.</p>

<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: &quot;Consolas&quot;, consolas, monospace; font-size: 8pt; cursor: text; direction: ltr; max-height: 200px; background-color: rgb(244, 244, 244);">
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Consolas&quot;, consolas, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">class</span> FooObserver<br />{<br />    <span style="color: rgb(0, 0, 255);">private</span> <span style="color: rgb(0, 0, 255);">readonly</span> Collection&lt;NotifyCollectionChangedEventArgs&gt; collectionChangedNotifications =<br />        <span style="color: rgb(0, 0, 255);">new</span> Collection&lt;NotifyCollectionChangedEventArgs&gt;();<br /><br />    <span style="color: rgb(0, 0, 255);">private</span> <span style="color: rgb(0, 0, 255);">readonly</span> Collection&lt;PropertyChangedEventArgs&gt; propertyChangedNotifications =<br />        <span style="color: rgb(0, 0, 255);">new</span> Collection&lt;PropertyChangedEventArgs&gt;();<br /><br />    <span style="color: rgb(0, 0, 255);">public</span> FooObserver(ObservableFoo foo)<br />    {<br />        ((INotifyCollectionChanged)foo.Strings).CollectionChanged += <span style="color: rgb(0, 0, 255);">this</span>.ObservableStringsOnCollectionChanged;<br />        ((INotifyPropertyChanged)foo.Strings).PropertyChanged += <span style="color: rgb(0, 0, 255);">this</span>.OnPropertyChanged;<br />        foo.PropertyChanged += <span style="color: rgb(0, 0, 255);">this</span>.OnPropertyChanged;<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">public</span> ReadOnlyCollection&lt;NotifyCollectionChangedEventArgs&gt; CollectionChangedNotifications<br />    {<br />        get<br />        {<br />            <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">new</span> ReadOnlyCollection&lt;NotifyCollectionChangedEventArgs&gt;(<span style="color: rgb(0, 0, 255);">this</span>.collectionChangedNotifications);<br />        }<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">public</span> ReadOnlyCollection&lt;PropertyChangedEventArgs&gt; PropertyChangedNotifications<br />    {<br />        get<br />        {<br />            <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">new</span> ReadOnlyCollection&lt;PropertyChangedEventArgs&gt;(<span style="color: rgb(0, 0, 255);">this</span>.propertyChangedNotifications);<br />        }<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">private</span> <span style="color: rgb(0, 0, 255);">void</span> ObservableStringsOnCollectionChanged(<span style="color: rgb(0, 0, 255);">object</span> sender, NotifyCollectionChangedEventArgs args)<br />    {<br />        <span style="color: rgb(0, 0, 255);">this</span>.collectionChangedNotifications.Add(args);<br />    }<br /><br />    <span style="color: rgb(0, 0, 255);">private</span> <span style="color: rgb(0, 0, 255);">void</span> OnPropertyChanged(<span style="color: rgb(0, 0, 255);">object</span> sender, PropertyChangedEventArgs args)<br />    {<br />        <span style="color: rgb(0, 0, 255);">this</span>.propertyChangedNotifications.Add(args);<br />    }<br />}<br /></pre>

  <br /></div>

<h3>What Now?</h3>

<p>Frankly, I hate to ship another assembly, thankfully NuGet will make this less painful. If this works as well as it appears to, I suppose I will start shipping data binding friendly versions of some of the types found in Microsoft.Activities.Extensions. Am I on the right track? After all, I could be missing something obvious. I could just make the base classes data binding friendly and make everyone reference System.Windows. The performance penalty is not that great, but then when there is a good solution why not use it? </p>

<p>Happy Coding!</p>

<p>Ron Jacobs 
  <br />blog: <a href="http://blogs.msdn.com/rjacobs">http://blogs.msdn.com/rjacobs</a> 

  <br />Twitter: <a href="https://twitter.com/ronljacobs">@ronljacobs</a></p>]]></content:encoded>
    </item>
    <item>
      <title>My Essential Development Tools</title>
      <link>https://docs.microsoft.com/archive/blogs/rjacobs/my-essential-development-tools</link>
      <pubDate>Tue, 10 Jul 2012 06:44:34 GMT</pubDate>
      <dc:creator><![CDATA[Ron Jacobs]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/rjacobs/2012/07/10/my-essential-development-tools/</guid>
      <description><![CDATA[There are a few development tools that I just can’t live without.  ReSharper  A few years ago I was...]]></description>
      <content:encoded><![CDATA[<p>There are a few development tools that I just can’t live without.</p>  <h3>ReSharper</h3>  <p>A few years ago I was sitting in <a href="http://blogs.msdn.com/b/gblock/">Glenn Block’s</a> office when I noticed some strange additions to Visual Studio.&#160; When I asked him about it he said “That’s ReSharper” and I was hooked.&#160; I had to have it.</p>  <p><a href="http://www.jetbrains.com/resharper/">ReSharper</a> helps me to write better code faster period.&#160; This is my #1 must have tool.</p>  <h3>NCrunch</h3>  <p>This is my most recent addition to the list.&#160; I’m a big believer in unit testing and understanding your code coverage is crucial.&#160; Yes Visual Studio has unit testing and code coverage but… if you have a large project the cycle of build, test, check code coverage just takes way too long.</p>  <p>With <a href="http://ncrunch.net/">NCrunch</a> I just work away and it builds, tests and analyzes code coverage in the background.&#160;&#160; Before you know it you have red, green and black dots telling you about the coverage.&#160; If a test fails, I see it right away and can fix it even before I built the project or even saved the file!.</p>  <h3>StyleCop</h3>  <p>I remember the good old days when teams used to fight about things like tabs vs. spaces in code or where to put your curly braces.&#160; StyleCop stops all the fighting – it has a set of rules for code style that for the most part I agree with.&#160; It analyzes my code and tells me when I’m not complying with the style as I type.</p>  <p>If you put <a href="http://stylecop.codeplex.com/">StyleCop</a> together with ReSharper – now you can quickly format your code.&#160; Got to have this tool.</p>  <h3>CleanProject</h3>  <p>Have you ever wanted to email a project to a colleague or upload it to some website only to find that with all the bin / obj / ReSharper / etc. folder full of stuff that the zip file was huge?&#160; Or maybe you open a project from a website or a friend and Visual Studio informs you that the project was under source control and the server is not available.</p>  <p>I created <a href="http://wf.codeplex.com/wikipage?title=Clean%20Project%20Overview">CleanProject</a> as a tool to remove crap that I don’t care about from the zip file and to remove source control bindings.&#160; Seems that several thousand of you agree that CleanProject is pretty useful.</p>  <h3>.NET Reflector</h3>  <p align="left">Yes, I work at Microsoft and yes I have access to all the .NET Framework source (you do too by the way) but often I find that it is faster and easier for me to analyze what some piece of the .NET framework is doing by simply going to <a href="http://www.reflector.net/">.NET Reflector</a>.&#160; They recently release a great extension for Visual Studio 2012 which makes it even better.&#160; I can’t tell you how many times where understanding the underlying class has helped me to solve a difficult bug.</p>  <h3 align="left"></h3>]]></content:encoded>
    </item>
  </channel>
</rss>