<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>My Sacy Developer Life in Shanghai!</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/isaacy/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/isaacy/feed.xml</link>
    <description>Windows workflow, azure, and developer&amp;#039;s life in China</description>
    <lastBuildDate>Wed, 17 Apr 2019 03:48:41 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Working with ModelItem inside IActivityTemplateFactory in PU1</title>
      <link>https://docs.microsoft.com/archive/blogs/isaacy/working-with-modelitem-inside-iactivitytemplatefactory-in-pu1</link>
      <pubDate>Thu, 18 Aug 2011 09:22:50 GMT</pubDate>
      <dc:creator><![CDATA[Isaac Yuen MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/isaacy/2011/08/18/working-with-modelitem-inside-iactivitytemplatefactory-in-pu1/</guid>
      <description><![CDATA[&#160;  Note: this one I meant to talk about this for a long time.&#160; After this, I actually...]]></description>
      <content:encoded><![CDATA[<blockquote></blockquote>  <p>&#160;</p>  <p><em>Note: this one I meant to talk about this for a long time.&#160; After this, I actually ran out of immediate topics for WF.&#160; So any suggestions are welcomed.</em></p>  <p>Back in July, we received a customer request that <a href="https://msdn.microsoft.com/en-us/library/system.activities.presentation.iactivitytemplatefactory.aspx">IActivityTemplateFactory</a> does not work anymore after he installed .Microsoft .NET Framework 4 Platform Update 1 (<a href="https://support.microsoft.com/kb/2478063">KB2478063</a>).&#160; It was the first issue we saw after the Platform Update shipped, and I was more nervous than others, because I was the primary dev for the WF activity/designer at that time and fixed the majority of the bugs.&#160; I wasn’t sure if I just introduced a recall-scale bug.&#160; I was on the servicing loop at the time so after some initial investigation, I was tasked to find out the root cause.</p>  <p>In the customer’s scenario, he has a rehoster with a Flowchart as a root.&#160; The rehost app has a Flowchart as the root activity.&#160; He also created an IActivitytemplateFactory which would place two connected flownodes in the FlowchartDesigner:</p>   <div id="codeSnippetWrapper">   <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">     <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum1">   1:</span> Activity IActivityTemplateFactory.Create(DependencyObject target)</pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2">   2:</span> {</pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum3">   3:</span>   ActivityDesigner designer = target <span style="color: #0000ff">as</span> ActivityDesigner;</pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum4">   4:</span>   FlowStep step = <span style="color: #0000ff">new</span> FlowStep();</pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum5">   5:</span>   Assign assign = <span style="color: #0000ff">new</span> Assign();</pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum6">   6:</span>   step.Action = assign;</pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum7">   7:</span>   FlowDecision decision = <span style="color: #0000ff">new</span> FlowDecision();</pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum8">   8:</span>   step.Next = decision;</pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum9">   9:</span>   designer.ModelItem.Properties[<span style="color: #006080">&quot;Nodes&quot;</span>].Collection.Add(step);</pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum10">  10:</span>   designer.ModelItem.Properties[<span style="color: #006080">&quot;Nodes&quot;</span>].Collection.Add(decision);</pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum11">  11:</span>   ModelItem decisionItem = designer.ModelItem.Properties[<span style="color: #006080">&quot;Nodes&quot;</span>].Collection[1];</pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum12">  12:</span>   ModelItem stepItem = designer.ModelItem.Properties[<span style="color: #006080">&quot;Nodes&quot;</span>].Collection[0];</pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum13">  13:</span>   <span style="color: #0000ff">return</span> <span style="color: #0000ff">null</span>;</pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum14">  14:</span> }</pre>
<!--CRLF--></div>
</div>

<p>So far so good right?&#160; And you wouldn’t expect any problem when you drag this Factory to the Flowchart right?&#160; Try this on your own!</p>

<p>If you have PU1, you would discover that the drag operation would throw an ugly ArgumentOutOfRangeException at line 3:
  <div id="codeSnippetWrapper">
    <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">
      <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum1">   1:</span> designer.ModelItem.Properties[<span style="color: #006080">&quot;Nodes&quot;</span>].Collection.Add(step);</pre>
<!--CRLF-->

      <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2">   2:</span> designer.ModelItem.Properties[<span style="color: #006080">&quot;Nodes&quot;</span>].Collection.Add(decision);</pre>
<!--CRLF-->

      <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum3">   3:</span> ModelItem decisionItem = designer.ModelItem.Properties[<span style="color: #006080">&quot;Nodes&quot;</span>].Collection[1];</pre>
<!--CRLF--></div>
  </div>
</p>


<p>This was surprising – you would expect the “1” index would return the FlowDecision ModelItem but it throws an Exception instead.&#160; Then we tried to look at the Collection.Count at Line 3 and we discovered that FlowDecision node was not inserted:</p>

<div id="codeSnippetWrapper">
  <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum1">   1:</span> designer.ModelItem.Properties[<span style="color: #006080">&quot;Nodes&quot;</span>].Collection.Add(step);</pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2">   2:</span> designer.ModelItem.Properties[<span style="color: #006080">&quot;Nodes&quot;</span>].Collection.Add(decision);</pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum3">   3:</span> Debug.Assert(designer.ModelItem.Properties[<span style="color: #006080">&quot;Nodes&quot;</span>].Collection.Count == 2);</pre>
<!--CRLF--></div>
</div>

<p>Guess what the Collection.Count is: 2? 1? No… it’s ZERO!&#160; So it appeared as if nothing was inserted into the collection!&#160; As we debugged the return value of Collection.Add, it was not null and was a ModelItem that wrapped around the FlowNode that was inserted to the FlowchartDesigner.&#160; As this moment, I realized that the it was actually caused by a fix we did for PU1.&#160; But before that, let’s give you some background.</p>

<p>The ModelItem object model provides an API which merges multiple ModelItem operations into a single unit of work – you can consider <a href="https://blogs.msdn.com/b/kushals/archive/2009/10/27/adding-activities-on-the-designer-programmatically.aspx">EditingScope</a> as a transaction, where all the changes are not committed until you declare EditingScope.Complete().&#160; Inside an EditingScope though, any ModelItem operation would not change the state of the object model, until Complete is called.</p>

<p>However, if you try to drag this composite FlowNodes to a Dev10 RTM Flowchart and then undo, you will observe that only the FlowDecision is undone, but the Assign remains in the Flowchart.&#160; That’s because the Drag operation is not wrapped inside an EditingScope.&#160; So each ModelItem operation is independent.&#160; Even though it appeared as if you dragged one item to the Flowchart, there were multiple operations (what we called UndoUnit).</p>

<p>Normally, this is not a blocking issue.&#160; However, we found another problem later – if you drag an Activityto the edge of a Flowchart, this drop operation would automatically expand the Flowchart to be big enough to contain the dropped Activity.&#160; Now, if you try to undo it, you will realize that the drag operation is undone, but Flowchart still has the expanded size.&#160; This problem eventually became more annoying with StateMachine, and we eventually decided to fix it by wrapping the drap-drop operation inside an EditingScope.</p>

<p>So far so good… now there is only one UndoUnit for drag-drop operation and the size would be restored properly.&#160; What we didn’t realize was that there were customers who had dependency on ModelItem state, and this fix would break their rehost app.</p>

<p>Wrapping the drag-drop operation into a single EditingScope is still the right thing to do.&#160; And if you are a WF ModelItem developer, you might already see that the customer’s code is not the only way to solve the problem.&#160; Eventually, we recommended the customer to workaround this problem by not depending on Count of Indexes on the collection, but operate on the return value of the Add operation instead:</p>

<div id="codeSnippetWrapper">
  <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum1">   1:</span> ModelItem decisionMI = designer.ModelItem.Properties[<span style="color: #006080">&quot;Nodes&quot;</span>].Collection.Add(decision);</pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 78.64%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; height: 16px; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2">   2:</span> ModelItem stepMI = designer.ModelItem.Properties[<span style="color: #006080">&quot;Nodes&quot;</span>].Collection.Add(step);</pre>
<!--CRLF--></div>
</div>


<p>And a single advisory for all WF designer developer:</p>

<p><em><strong>In IActivityTemplateFactory, do not rely any property or index values of any ModelItemCollection or ModelitemDictionary, because the caller might be in an EditingScope.</strong></em></p>

<p>However, this behavior is unacceptable, and in Dev11 we have enough new WF functionalities such that the drag-drop can still be in ONE EditingScope, but all the Add/Remove would change the state of the Collection!&#160; Isn’t that wonderful?&#160; A very smart dev called Tony Tang has completed this work and you will see this in Dev11!</p>

<p>Anyway, it is a small fix, but it was interesting (I think) nevertheless, so I wanted to write this story down.</p>

<p>Now, I really need to think hard what I should write next…</p>]]></content:encoded>
    </item>
    <item>
      <title>Defining Composite State in WF4 StateMachine</title>
      <link>https://docs.microsoft.com/archive/blogs/isaacy/defining-composite-state-in-wf4-statemachine</link>
      <pubDate>Mon, 15 Aug 2011 02:59:56 GMT</pubDate>
      <dc:creator><![CDATA[Isaac Yuen MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/isaacy/2011/08/15/defining-composite-state-in-wf4-statemachine/</guid>
      <description><![CDATA[&#160;  Earlier last week, Tim sent me a forum post about asking why State is sealed.&#160; However,...]]></description>
      <content:encoded><![CDATA[<p>&#160;</p>  <p>Earlier last week, Tim sent me a forum post about asking why <a href="https://social.msdn.microsoft.com/Forums/en-US/wfprerelease/thread/da82be9d-e65e-460a-b40c-ccd9a711493a">State is sealed</a>.&#160; However, I searched around the web and did not find an answer for this.&#160; It is strange because sealing (“shipped”) activity is almost like the first thing that I learned.&#160; So I dug up some internal docs and found the answer:</p>  <p><font size="6">42.</font></p>  <p>…</p>  <p>Sorry it is a cold joke; there is indeed a less cold reason for sealing activity thought.&#160; It is really a philosophical decision: We expect that <a href="https://blogs.msdn.com/b/steverowe/archive/2008/04/28/prefer-composition-over-inheritance.aspx">Composition</a> is much better extension mechanism than inheritance.&#160; However, there are also some very valid reason for not allowing State to be extensible.&#160; For one, State is only an artifact that is relevant to StateMachine, so we want to make sure that only StateMachine can consume State.&#160; Also, unlike other activity, State scheduling is tightly integrated with State (that’s why it’s not an Activity).&#160; It would not make sense to allow State to be extensible, because StateMachine would not know how to schedule anything in State other than Entry and Exit.</p>  <p>(Aside of being philosophical, the one valid reason that I can think of where this might make sense, is when an ISV provides a set of out-of-box “composite” states to a StateMachine rehoster.&#160; However, the ISV wants to “seal” the users from changing the State or hide them from the complex logic in this composite state.&#160; In this case, making State “inheritable” would make sense - Microsoft can’t seal it because ISVs needs to seal it.&#160; A little bit ironic, but nevertheless, this would be valid.)</p>  <p>The recommended approach, however, is still to use a composite activity and make it available to user via <a href="https://msdn.microsoft.com/en-us/library/system.activities.presentation.iactivitytemplatefactory.aspx">IActivityTemplateFactroy</a>. There is a catch though.&#160; The <a href="https://msdn.microsoft.com/en-us/library/ee473817.aspx">IActivityTemplateFactory.Create</a> return an Activity instance.&#160; Normally, that would not be a problem, since most control flow activities (i.e. Sequence, Flowchart) accept an activity as a part of its children activities.&#160; However, StateMachine activity is composed by State, and State is not an Activity.&#160; So you cannot really returns an Activity in IActivityTemplateFactory.</p>  <p>Even if you create an “empty” Activity in IActivityTemplateFactory, you would not be able to drop it into a StateMachine, because StateMachine designer would accept only State.</p>  <p>Does it mean that you cannot create an out-of-box composite State for our ISV customer? --–screaming!---</p>  <p>Well the answer is <strong>NO</strong>, so don’t panic yet.&#160; What it means, is that you cannot drop a custom composite state from Toolbox to the StateMachine (and I guarantee you that it will be fixed in VS vNext).&#160; However, you can still add a composite state via. the ModelItem level though.</p>  <p>Assume that you’re creating your own rehost, when you are initializing the StateMachine, cache the StateModel modelItem.</p>  <pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> AddDesigner()
{ 
    <span class="kwrd">this</span>.workflowDesigner = <span class="kwrd">new</span> WorkflowDesigner();
    Grid.SetColumn(<span class="kwrd">this</span>.workflowDesigner.View, 1);

    ActivityBuilder builder = <span class="kwrd">new</span> ActivityBuilder();
    builder.Implementation = <span class="kwrd">new</span> StateMachine(); <span class="rem">// </span>
    <span class="kwrd">this</span>.workflowDesigner.Load(builder);
    ModelItem builderRoot = <span class="kwrd">this</span>.workflowDesigner.Context.Services.GetService&lt;ModelService&gt;().Root;
    
    <span class="rem">// NOTE: you need cache the StateMachine modelItem for later use</span>
    stateMachineModelItem = builderRoot.Properties[<span class="str">&quot;Implementation&quot;</span>].Value;
}</pre>

<p></p>

<p>Then we would add a button to the rehost.&#160; The button is used for adding the composition state to the cached StateMachine.</p>

<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> Button_Click(<span class="kwrd">object</span> sender, RoutedEventArgs e)
{
    stateMachineModelItem.Properties[<span class="str">&quot;InitialState&quot;</span>].SetValue(<span class="kwrd">null</span>);

    State s = <span class="kwrd">new</span> State()
        {
            DisplayName = <span class="str">&quot;Custom State&quot;</span>,
            Entry = <span class="kwrd">new</span> WriteLine()
            {
                    Text = <span class="kwrd">new</span> InArgument&lt;<span class="kwrd">string</span>&gt;(<span class="str">&quot;Hello world&quot;</span>)
            }
        };
    stateMachineModelItem.Properties[<span class="str">&quot;States&quot;</span>].Collection.Add(s);
    stateMachineModelItem.Properties[<span class="str">&quot;InitialState&quot;</span>].SetValue(s);
}</pre>

<p>In this case if you press the button, you can see the “custom state” in the rehost.</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/70/metablogapi/5775.image_0BDF8C93.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-70-metablogapi/5775.image_5F00_0BDF8C93.png"><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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/70/metablogapi/7024.image_thumb_57CAED3F.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-70-metablogapi/7024.image_5F00_thumb_5F00_57CAED3F.png" width="696" height="373" /></a></p>

<p>Let me know if it helps <img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/70/metablogapi/7433.wlEmoticon-smile_19EE55C3.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-70-metablogapi/7433.wlEmoticon_2D00_smile_5F00_19EE55C3.png" /></p>]]></content:encoded>
    </item>
    <item>
      <title>Patterns for Fault Handling Transition in State Machine</title>
      <link>https://docs.microsoft.com/archive/blogs/isaacy/patterns-for-fault-handling-transition-in-state-machine</link>
      <pubDate>Mon, 15 Aug 2011 00:33:55 GMT</pubDate>
      <dc:creator><![CDATA[Isaac Yuen MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/isaacy/2011/08/15/patterns-for-fault-handling-transition-in-state-machine/</guid>
      <description><![CDATA[Fault handling is one of the few things that people have asked about in WF4 StateMachine.&#160; The...]]></description>
      <content:encoded><![CDATA[<p>Fault handling is one of the few things that people have asked about in WF4 StateMachine.&#160; The most common scenario is to catch an exception when the StateMachine is executing, and then, do either of the followings:</p>  <ul>   <li>Remain in the current state </li>    <li>Jump to a Fault-Handling state and complete the workflow gracefully and restart again. </li> </ul>  <p>However, there is no built-in fault-tolerant mechanism in StateMachine.&#160; And there are very good reason for that.&#160; One, we want to keep StateMachine simple (so it is as easy to understand as Flowchart).&#160; Secondly, we really want all the movements within a StateMachine to be driven by Transitions – so if you do implement some fault-handling mechanism, you should be able to draw it in a State diagram and implement it.</p>  <p>Long ago, I did a very small doc on fault-handling.&#160; Assuming most of the heavy-lifting of StateMachine happens in Trigger, you can put a Try-Catch in a Trigger and then StateMachine scheduling mechanism should do all other things for you (so you don’t need to schedule activity yourself.</p>  <h5>Fault Handling Pattern for Non-Shared Receive/SendReply transition using Try-Catch Handler by adding a Shared Trigger transition</h5>  <p>   <table border="0" cellspacing="0" cellpadding="2" width="690"><tbody>       <tr>         <td valign="top" width="238">Step 1:            <br />Create a boolean value with “True” default value.             <br />Encapsulate a Try-Catch to the current operation in the Trigger.             <br />In the original “Condition” section, specify the boolean variable there.&#160; Under normal condition, this variable should always be true, so the State would transition out as normal.</td>          <td valign="top" width="450"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/70/metablogapi/3414.image20_5A8B36A8.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-70-metablogapi/3414.image20_5F00_5A8B36A8.png"><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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/70/metablogapi/7128.image20_thumb_2361A8AF.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-70-metablogapi/7128.image20_5F00_thumb_5F00_2361A8AF.png" width="387" height="298" /></a>            <br /></td>       </tr>        <tr>         <td valign="top" width="238">Step 2:            <br />In the Catch block, you define the Exception that you want to catch, and also the error-handling logic.&#160; The boolean variable would be assigned to ”false”.             <br />So if an exception happened, the boolean variable would be ‘false’.&#160; In this case, no transition would happen and the StateMachine would remain in the current State</td>          <td valign="top" width="450"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/70/metablogapi/8284.image26_2F16EFE1.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-70-metablogapi/8284.image26_5F00_2F16EFE1.png"><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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/70/metablogapi/5226.image26_thumb_3E6A51F0.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-70-metablogapi/5226.image26_5F00_thumb_5F00_3E6A51F0.png" width="386" height="284" /></a>            <br /></td>       </tr>        <tr>         <td valign="top" width="238">Optional Step 3:            <br />If you want the StateMachine to transition to an error handling state, then you simply create a shared triggered transition out of the current state.&#160; In this Transition, the condition if the negation of the boolean variable.&#160; So it would transition out if an Exception occurs!</td>          <td valign="top" width="450"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/70/metablogapi/2425.image30_03367625.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-70-metablogapi/2425.image30_5F00_03367625.png"><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="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/70/metablogapi/8284.image30_thumb_6FA91683.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-70-metablogapi/8284.image30_5F00_thumb_5F00_6FA91683.png" width="314" height="83" /></a></td>       </tr>     </tbody></table> </p>  <p>The good thing about this approach is that you can re-use the execution mechanism to prevent a StateMachine from transition.&#160; The constraint though, is that it requires your Trigger to be non-shared.&#160; I would imagine that this approach would be more useful in Workflow Service scenario (where each “Receive” activity is its own transition).&#160; </p>  <p>However, if you already have a shared trigger and you want to handle error this transition, what can you do?&#160; The most elegant way that I could think of (at the same when I was drafting it) was to use an intermediate state to catch the error:</p>  <h5>Fault-Handling Pattern with Shared Trigger with one Receive and Multiple Fault-Handling SendReply by Using Null Trigger </h5>  <table border="0" cellspacing="0" cellpadding="0" width="555"><tbody>     <tr>       <td valign="top" width="206">         <p>Between the original Source and the Destination State, create two State:</p>          <p>1. One &quot;immediate&quot; state designed to evaluate the result of the Action</p>          <p>2. Another &quot;fault-handling&quot; state that could be the destination of the &quot;immediate&quot; state</p>       </td>        <td valign="top" width="347"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/70/metablogapi/8204.image34_06F41AF5.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-70-metablogapi/8204.image34_5F00_06F41AF5.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/70/metablogapi/5148.image34_thumb_450D35A6.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-70-metablogapi/5148.image34_5F00_thumb_5F00_450D35A6.png" width="196" height="223" /></a>          <br /></td>     </tr>      <tr>       <td valign="top" width="206">         <p>Within the original transition, if we want to handle any potential fault from Transition.Action activity:</p>          <p>0. encapsulate any activity with a Try-Catch activity</p>          <p>1. In the Catch block, have an &quot;Assign&quot; activity that would set a flag to false (NOTE: because this flag must be shared between two states, it has to be declared at the StateMachine level)</p>          <p>2. The Transition is target at the immediate &quot;Verifying state&quot;</p>       </td>        <td valign="top" width="347"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/70/metablogapi/4075.image41_3C3D2D5A.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-70-metablogapi/4075.image41_5F00_3C3D2D5A.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/70/metablogapi/8688.image41_thumb_47F2748C.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-70-metablogapi/8688.image41_5F00_thumb_5F00_47F2748C.png" width="259" height="277" /></a>          <br /></td>     </tr>      <tr>       <td valign="top" width="206">         <p>Within the Fault-Decision State:</p>          <p>1. Create a Null-Trigger transition, that would transition to original Destination state if the result is &quot;true&quot; (by default)</p>          <p>2. If the flag is evaluated to &quot;false&quot;, transition to the Fault-Handling (i.e &quot;Bad State&quot;, or event the original State)</p>       </td>        <td valign="top" width="347"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/70/metablogapi/1016.image46_3EB6394B.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-70-metablogapi/1016.image46_5F00_3EB6394B.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/70/metablogapi/6138.image46_thumb_6A1A5A45.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-44-70-metablogapi/6138.image46_5F00_thumb_5F00_6A1A5A45.png" width="258" height="310" /></a></td>     </tr>   </tbody></table>  <p>See if these patterns would be helpful to you!</p>  <p>Isaac @ Shanghai</p>]]></content:encoded>
    </item>
    <item>
      <title>How to create your own MSDN blog and link it with Windows Live Writer</title>
      <link>https://docs.microsoft.com/archive/blogs/isaacy/how-to-create-your-own-msdn-blog-and-link-it-with-windows-live-writer</link>
      <pubDate>Tue, 19 Apr 2011 10:27:26 GMT</pubDate>
      <dc:creator><![CDATA[Isaac Yuen MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/isaacy/2011/04/19/how-to-create-your-own-msdn-blog-and-link-it-with-windows-live-writer/</guid>
      <description><![CDATA[After working in Microsoft for almost 3 years, finally I decided to get my own blog to celebrate...]]></description>
      <content:encoded><![CDATA[<p><font size="3"></font></p>  <p><font size="2">After working in Microsoft for almost 3 years, finally I decided to get my own blog to celebrate my </font><a href="https://msdn.microsoft.com/en-us/library/ee264171.aspx"><font size="2">first important work</font></a><font size="2"> at ADX in China.&#160; But searching through the setting I cannot see any place that allowed me to click the “Create Blog” button!</font></p>  <p><font color="#ff0000" size="2"><em>Reminder: I was later reminded that only Microsoft FTE can create a MSDN blog, so this blog is probably not that interesting to everyone.&#160; </em></font></p>  <p><em><font size="2"></font></em></p>  <p><font size="2">Searching online, I found this </font><a href="https://blogs.msdn.com/b/rajdey/archive/2011/03/18/how-to-create-a-msdn-blog.aspx"><font size="2">article</font></a><font size="2"> from another softie and it was helpful so I thought I should share it as well.</font></p>  <h1></h1>  <h1>Create a MSDN blog</h1>  <h1></h1>  <h1></h1>  <ol>   <li><font size="2">Go to </font><a href="https://blogs.msdn.com/create-blog.aspx"><font size="2">https://blogs.msdn.com/create-blog.aspx</font></a></li>    <li><font size="2">In <em>Blog Name</em>, you have your <em>once-in-a-lifetime </em>chance to specify a name for your blog.&#160; It is going to the address for your blog (i.e. blogs.msdn.com/b/<em>your-specified-name</em>).&#160; However, I created my first blog by typing a random name and realized that a MSDN blog is not removable!</font></li>    <li><font size="2">After clicking the <em>Create</em> button, you would get your own blog!</font></li> </ol>  <p><font size="2">However, MSDN blog is not as manageable as other blogging services like WordPress.&#160; And it is unimaginable that anyone would not use a blog editor to post blog.&#160; For that matter, Windows Live Writer comes to my mind as the natural choice.&#160; However, trying to hook WLW with MSDN blog is not as easy as 1-2-3.</font></p>  <p><font size="2">When I tried to add MSDN blog account to WLW as “Other Services”, it prompted me for:</font></p> <font size="3">   <ul>     <li><font size="2">My blog address (so blogs.msdn.com/b/isaacy)</font></li>      <li><font size="2">User name &amp; Password</font></li>   </ul>    <p><font size="2">You would think, that the MSDN blog account would be linked to the MSDN account, which uses Live ID.&#160; But I was totally wrong on that.&#160; Searching online again I found this </font><a href="https://social.microsoft.com/Forums/en/writergeneral/thread/8a8b5771-4956-4ed2-bdc4-d99ba748eb51"><font size="2">MSDN forum post</font></a><font size="2">: </font><a href="https://social.microsoft.com/Forums/en/writergeneral/thread/8a8b5771-4956-4ed2-bdc4-d99ba748eb51"><font size="2">Windows Live Writer Fails When Connecting to blogs.msdn.com</font></a><font size="2">.</font></p>    <p><font size="2">It turns out that MSDN blog account and MSDN account (Live ID) are two separate things!&#160; And you are expected to specify another unique password for MSDN blog (and add another password to the list of stuff that I would need to remember).&#160; The forum post said that the account name is the <em>account</em> name appeared on the top right corner of the page.&#160; But again, this was not applicable to my case.&#160; After play with this for a little while, finally I figured out the easiest way to get this done.</font></p>    <h2></h2>    <h1></h1>    <h1></h1>    <h2></h2>    <h1></h1>    <h4>Fastest way to link a MSDN blog with Windows Live Writer</h4>    <ol>     <li><font size="2">Go to “Setting” – “Change Password”, say that you forget the password and ask for the password in email.</font></li>      <li><font size="2">After you receive the email, click the “Reset Password” link, and specify your password.</font></li>      <li><font size="2">In WLW – “Publish: Add blog account”, type:</font></li>      </ol><ol>       <li><font size="2">Your blog address</font></li>        <li><font size="2">Your LIVE ID account name! (yes! your_name _at_ hotmail _dot_ com!&#160; it’s not your “ABC [MSFT]” name!</font></li>        <li><font size="2">Your reset password</font></li>     </ol>       <p><font size="2">WLW would then try to configure the account.&#160; After everything is setup, then you’re on track to write your first blog post!</font></p>    <p><font size="2">Have a good time blogging!</font></p>    <p><font size="2">Isaac</font></p>    <br /></font>]]></content:encoded>
    </item>
  </channel>
</rss>