<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Yun Jin's WebLog</title><link>http://blogs.msdn.com/b/yunjin/</link><description>CLR internals, Rotor code explanation, CLR debugging tips, trivial debugging notes, .NET programming pitfalls, and blah, blah, blah...</description><dc:language>en-US</dc:language><generator>Telligent Evolution Platform Developer Build (Build: 5.6.50428.7875)</generator><item><title>Workflow Foundation 4.0 Activity Data Model (III)</title><link>http://blogs.msdn.com/b/yunjin/archive/2010/04/28/workflow-foundation-4-0-activity-data-model-iii.aspx</link><pubDate>Wed, 28 Apr 2010 21:43:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10004147</guid><dc:creator>Yun Jin</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/yunjin/rsscomments.aspx?WeblogPostID=10004147</wfw:commentRss><comments>http://blogs.msdn.com/b/yunjin/archive/2010/04/28/workflow-foundation-4-0-activity-data-model-iii.aspx#comments</comments><description>I finally finished the long overdued &lt;A title="Workflow Activity Variable" href="http://blogs.msdn.com/flow/archive/2010/04/27/workflow-foundation-4-0-activity-data-model-iii.aspx" mce_href="http://blogs.msdn.com/flow/archive/2010/04/27/workflow-foundation-4-0-activity-data-model-iii.aspx"&gt;last installment&amp;nbsp;of the Activity Data Model series&lt;/A&gt;. In this post, I focused on workflow variables. Conceptually workflow variables&amp;nbsp;are very similar to variables in procedure programming languages like C#. But one thing special about workflow variables is the concept of "public" versus "implementation" variables. "Public" variables means variables defined by activity users and could not be used by the activity's implementation. "Implementation" variables are very similiar to the concept of local varible in C#. Both variables and arguments are scoped in WF4, which is a big improvement compared to WF3.&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10004147" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/yunjin/archive/tags/Go+with+the+flow/">Go with the flow</category></item><item><title>The first wave of WF4 Activity Packs are released</title><link>http://blogs.msdn.com/b/yunjin/archive/2010/04/25/the-first-wave-of-wf4-activity-packs-are-released.aspx</link><pubDate>Sun, 25 Apr 2010 13:31:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10002147</guid><dc:creator>Yun Jin</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/yunjin/rsscomments.aspx?WeblogPostID=10002147</wfw:commentRss><comments>http://blogs.msdn.com/b/yunjin/archive/2010/04/25/the-first-wave-of-wf4-activity-packs-are-released.aspx#comments</comments><description>&lt;P style="MARGIN: 0in 0in 10pt" class=MsoNormal&gt;&lt;FONT size=3 face=Calibri&gt;I'm very happy to annouce that&amp;nbsp;my team&amp;nbsp;just released 2 pack of Activities for WF4 on &lt;/FONT&gt;&lt;A href="http://wf.codeplex.com/" mce_href="http://wf.codeplex.com/"&gt;&lt;FONT size=3 face=Calibri&gt;CodePlex&lt;/FONT&gt;&lt;/A&gt;!&lt;/P&gt;
&lt;P style="TEXT-INDENT: -0.25in; MARGIN: 0in 0in 0pt 0.5in; mso-list: l0 level1 lfo1" class=MsoListParagraphCxSpFirst&gt;&lt;SPAN style="FONT-FAMILY: Symbol; mso-fareast-font-family: Symbol; mso-bidi-font-family: Symbol"&gt;&lt;SPAN style="mso-list: Ignore"&gt;&lt;FONT size=3&gt;·&lt;/FONT&gt;&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;A title="State Machine Activity Pack" href="http://wf.codeplex.com/releases/view/43586" mce_href="http://wf.codeplex.com/releases/view/43586"&gt;&lt;FONT color=#0000ff size=3 face=Calibri&gt;State Machine Activity Pack&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Calibri&gt;&lt;FONT size=3&gt;. &lt;BR&gt;State Machine is one of the most common asks for WF4’s Activity Palette, especially for WF3 users. This Activity Pack includes a feature-rich State Machine supporting entry action, exit action, conditional transition, nested state, and etc. &lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;The designer supports free form editing experience similar to FlowChart. We also released all the source code so everyone could see how to implement such a complicated Activity. You are welcome to download the Activity, give it a try for your scenarios, and let us know how you think.&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="TEXT-INDENT: -0.25in; MARGIN: 0in 0in 0pt 0.5in; mso-list: l0 level1 lfo1" class=MsoListParagraphCxSpMiddle&gt;&lt;SPAN style="FONT-FAMILY: Symbol; mso-fareast-font-family: Symbol; mso-bidi-font-family: Symbol"&gt;&lt;SPAN style="mso-list: Ignore"&gt;&lt;FONT size=3&gt;·&lt;/FONT&gt;&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;A title="ADO.Net Activity Pack" href="http://wf.codeplex.com/releases/view/43585" mce_href="http://wf.codeplex.com/releases/view/43585"&gt;&lt;FONT color=#0000ff size=3 face=Calibri&gt;ADO.Net Activity Pack&lt;/FONT&gt;&lt;/A&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;.&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 10pt 0.5in" class=MsoListParagraphCxSpLast&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;WF4 does not have any out-of-box Activities for data access. Yet we believe data access is critical for workflow driven business applications. The set of Activities in this pack could execute SQL statements using ADO.Net. Designers for those Activities have some cool interaction with Visual Studio when it’s hosted in VS. For example, developers could access data source defined in VS’s solution explorer and connection string in config files. This is just a start, we are thinking hard about what data access experience should be for WF. So any of your feedback is appreciated.&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10002147" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/yunjin/archive/tags/Go+with+the+flow/">Go with the flow</category></item><item><title>Workflow Foundation 4.0 Activity Data Model (II)</title><link>http://blogs.msdn.com/b/yunjin/archive/2010/04/06/workflow-foundation-4-0-activity-data-model-ii.aspx</link><pubDate>Wed, 07 Apr 2010 01:16:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9991491</guid><dc:creator>Yun Jin</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/yunjin/rsscomments.aspx?WeblogPostID=9991491</wfw:commentRss><comments>http://blogs.msdn.com/b/yunjin/archive/2010/04/06/workflow-foundation-4-0-activity-data-model-ii.aspx#comments</comments><description>&lt;P&gt;Here comes &lt;A title="Workflow Activity Argument" href="http://blogs.msdn.com/flow/archive/2010/04/06/workflow-foundation-4-0-activity-data-model-ii.aspx" mce_href="http://blogs.msdn.com/flow/archive/2010/04/06/workflow-foundation-4-0-activity-data-model-ii.aspx"&gt;sequal of my WF4 Activity Data Model blog&lt;/A&gt;. This post focuses on WF arguments: the Argument class hierarchy which models arguments for WF; how to "declare" an argument for an activity; the automatic reflection; how to deal with dynamic arguments; what does expressions mean for WF; how to bind arguments to expressions; activity arguments evaluation order, and etc.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The next post will be about WF variables.&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9991491" width="1" height="1"&gt;</description></item><item><title>Workflow Foundation 4.0 Activity Data Model (I)</title><link>http://blogs.msdn.com/b/yunjin/archive/2010/04/05/workflow-foundation-4-0-activity-data-model-i.aspx</link><pubDate>Tue, 06 Apr 2010 01:37:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9990881</guid><dc:creator>Yun Jin</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/yunjin/rsscomments.aspx?WeblogPostID=9990881</wfw:commentRss><comments>http://blogs.msdn.com/b/yunjin/archive/2010/04/05/workflow-foundation-4-0-activity-data-model-i.aspx#comments</comments><description>&lt;P&gt;This is &lt;A title="Workflow Activity Data Model" href="http://blogs.msdn.com/flow/archive/2010/04/05/workflow-foundation-4-0-activity-data-model-i.aspx" mce_href="http://blogs.msdn.com/flow/archive/2010/04/05/workflow-foundation-4-0-activity-data-model-i.aspx"&gt;my first post about&amp;nbsp;WF4's Activity Data Model&lt;/A&gt;. The focus of this post is a high level principle which drives data model redesign between WF3 and WF4: separation of data and program. WF3 has Activity's&amp;nbsp;runtime state&amp;nbsp;stored in the Activity itself which caused a lot of problems. WF4 abstracts out concept like Argument and Variable&amp;nbsp;and pushes the real storage to ActivityContext available only at runtime. This model is consistent with mainstream programming languages like C#.&lt;/P&gt;
&lt;P&gt;I'll have&amp;nbsp;more posts later to talk about WF Argument and Variable in details.&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9990881" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/yunjin/archive/tags/Go+with+the+flow/">Go with the flow</category></item><item><title>Workflow Foundation 4.0 Activity Model (II)</title><link>http://blogs.msdn.com/b/yunjin/archive/2010/02/01/workflow-foundation-4-0-activity-model-ii.aspx</link><pubDate>Mon, 01 Feb 2010 14:27:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9956314</guid><dc:creator>Yun Jin</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/yunjin/rsscomments.aspx?WeblogPostID=9956314</wfw:commentRss><comments>http://blogs.msdn.com/b/yunjin/archive/2010/02/01/workflow-foundation-4-0-activity-model-ii.aspx#comments</comments><description>&lt;P&gt;I just posted the &lt;A title="Workflow Activity sample" href="http://blogs.msdn.com/flow/archive/2010/01/31/workflow-foundation-4-0-activity-model-ii.aspx" mce_href="http://blogs.msdn.com/flow/archive/2010/01/31/workflow-foundation-4-0-activity-model-ii.aspx"&gt;2nd half of introduction to WF4's Activity Model&lt;/A&gt;. In this blog, I have given examples of building 2 activities with 4 different authoring styles: how to build a leaf activity (HttpGet) using CodeActivity and AsyncCodeActivity; and how to build a composite activity (World) using Activity and NativeActivity.&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9956314" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/yunjin/archive/tags/Go+with+the+flow/">Go with the flow</category></item><item><title>Workflow Foundation 4.0 Activity Model (I)</title><link>http://blogs.msdn.com/b/yunjin/archive/2010/01/25/workflow-foundation-4-0-activity-model-i.aspx</link><pubDate>Mon, 25 Jan 2010 13:57:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9952958</guid><dc:creator>Yun Jin</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/yunjin/rsscomments.aspx?WeblogPostID=9952958</wfw:commentRss><comments>http://blogs.msdn.com/b/yunjin/archive/2010/01/25/workflow-foundation-4-0-activity-model-i.aspx#comments</comments><description>I just posted&amp;nbsp;&lt;A title="Workflow Activity Model" href="http://blogs.msdn.com/flow/archive/2010/01/24/lights-camera-activities-windows-workflow-foundation-s-activity-model.aspx" mce_href="http://blogs.msdn.com/flow/archive/2010/01/24/lights-camera-activities-windows-workflow-foundation-s-activity-model.aspx"&gt;one entry&amp;nbsp;in our "Go with the Flow" team blog&lt;/A&gt; to explain Workflow foundation V4's Activity Model. In the blog, I&amp;nbsp;discussed&amp;nbsp;how Workflow is composed of&amp;nbsp;Activities and introduced basic Activity programming model in WF4. I quickly went over the 4 Activity base classes (&lt;EM&gt;Activity, CodeActivity, AsyncCodeActivity, and NativeActivity&lt;/EM&gt;)&amp;nbsp;for 4 different programing style (from fully decarlative to 100% imperative programing). I'll post another blog later for the same topic to give few examples on how to use those 4 classes.&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9952958" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/yunjin/archive/tags/Go+with+the+flow/">Go with the flow</category></item><item><title>A developer's view of Workflow</title><link>http://blogs.msdn.com/b/yunjin/archive/2010/01/14/a-developer-s-view-of-workflow.aspx</link><pubDate>Fri, 15 Jan 2010 01:17:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9948749</guid><dc:creator>Yun Jin</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/yunjin/rsscomments.aspx?WeblogPostID=9948749</wfw:commentRss><comments>http://blogs.msdn.com/b/yunjin/archive/2010/01/14/a-developer-s-view-of-workflow.aspx#comments</comments><description>&lt;P&gt;This is &lt;A class="" title="A deverloper's view of Workflow" href="http://blogs.msdn.com/flow/archive/2010/01/14/a-developer-s-view-of-workflow.aspx" mce_href="http://blogs.msdn.com/flow/archive/2010/01/14/a-developer-s-view-of-workflow.aspx"&gt;my first blog post about Windows Workflow Foundation (WF)&lt;/A&gt; on the &lt;A class="" title="Go with the flow" href="http://blogs.msdn.com/flow" mce_href="http://blogs.msdn.com/flow"&gt;"Go with the flow" team blog&lt;/A&gt;. In the post I briefly described some key benefits of Workflow as a programming language: Declarative programming, Continuation, Persistence, and instance management.&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9948749" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/yunjin/archive/tags/Go+with+the+flow/">Go with the flow</category></item><item><title>Hello world, again</title><link>http://blogs.msdn.com/b/yunjin/archive/2010/01/14/hello-world-again.aspx</link><pubDate>Fri, 15 Jan 2010 00:48:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9948746</guid><dc:creator>Yun Jin</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/yunjin/rsscomments.aspx?WeblogPostID=9948746</wfw:commentRss><comments>http://blogs.msdn.com/b/yunjin/archive/2010/01/14/hello-world-again.aspx#comments</comments><description>&lt;P&gt;I've disappeared for more than 4 years in blog space. During this time period, I left CLR team and worked for Microsoft's High Performance Computing (HPC) team for 3 years to build Windows based compute cluster infrastructure. One thing I'm particularly proud of is that in Super Computing 2008, &lt;A class="" href="http://www.networkworld.com/news/2008/111808-windows-hpc-supercomputer.html?fsrc=netflash-rss" mce_href="http://www.networkworld.com/news/2008/111808-windows-hpc-supercomputer.html?fsrc=netflash-rss"&gt;a system powered by our product (Windows HPC Server 2008) hits #10 in the world's Top 500 Super Computer list&lt;/A&gt;. Recently I joined Microsoft's Application Server Group (ASG) to work on Windows based application server products. Specially, my team focuses on Windows Workflow&amp;nbsp;Foundation (WF) and Windows Communication Foundation (WCF). I decide to start the blogging&amp;nbsp;hobby again to share more insights on WCF/WF. Please stay tuned. :)&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9948746" width="1" height="1"&gt;</description></item><item><title>Trivial debugging note - using WeakReference in finalizer</title><link>http://blogs.msdn.com/b/yunjin/archive/2005/08/31/458231.aspx</link><pubDate>Wed, 31 Aug 2005 19:42:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:458231</guid><dc:creator>Yun Jin</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/yunjin/rsscomments.aspx?WeblogPostID=458231</wfw:commentRss><comments>http://blogs.msdn.com/b/yunjin/archive/2005/08/31/458231.aspx#comments</comments><description>&lt;P&gt;Some time ago I saw a problem from a partner team in Microsoft that an &lt;EM&gt;InvalidOperationException&lt;/EM&gt; is thrown from &lt;EM&gt;WeakReference.IsAlive&lt;/EM&gt;. &lt;EM&gt;WeakReference&lt;/EM&gt; wraps weak &lt;EM&gt;GC handle&lt;/EM&gt; implemented in CLR's &lt;EM&gt;Execution Engine&lt;/EM&gt; (&lt;EM&gt;GC handle&amp;nbsp;&lt;/EM&gt;is also exposed by &lt;EM&gt;System.Runtime.InteropServices.GCHandle &lt;/EM&gt;which supports&amp;nbsp;not only weak&amp;nbsp;&lt;EM&gt;handles, &lt;/EM&gt;but other types too&lt;EM&gt;)&lt;/EM&gt;. A weak &lt;EM&gt;GC handle&lt;/EM&gt; will be allocated and assigned to the &lt;EM&gt;WeakReference&lt;/EM&gt; object when the &lt;EM&gt;WeakReference&lt;/EM&gt; object is created. As described by &lt;A href="http://www.msdn.microsoft.com/msdnmag/issues/1200/GCI2/default.aspx"&gt;Jeffrey Richiter&lt;/A&gt;, the weak &lt;EM&gt;GC handle&lt;/EM&gt; contains pointer to an object, if the object is collected by GC, the &lt;EM&gt;GC handle&lt;/EM&gt; will be cleared to NULL. Most of time &lt;EM&gt;WeakReference.IsAlive &lt;/EM&gt;returns &lt;EM&gt;true&lt;/EM&gt; or &lt;EM&gt;false&lt;/EM&gt; to indicate whether the tracked object is alive. The check is based on whether the underlying &lt;EM&gt;GC handle&lt;/EM&gt; contains a non-NULL pointer or NULL. Similarly, &lt;EM&gt;WeakReference.get_Target&lt;/EM&gt; will return a valid object reference or &lt;EM&gt;null&lt;/EM&gt;. But after the &lt;EM&gt;WeakReference&lt;/EM&gt; object itself becomes unrooted and finalized, the underlying &lt;EM&gt;GC handle&lt;/EM&gt; will be destroyed and any call to &lt;EM&gt;IsAlive&lt;/EM&gt; or &lt;EM&gt;get_Target&lt;/EM&gt; on the &lt;EM&gt;WeakReference&lt;/EM&gt; object will throw &lt;EM&gt;InvalidOperationException&lt;/EM&gt; in V1.X.&lt;/P&gt;
&lt;P&gt;How would any method being called on a finalized object? Well, if one object &lt;EM&gt;O&lt;/EM&gt; has a field &lt;EM&gt;WR&lt;/EM&gt; as &lt;EM&gt;WeakReference&lt;/EM&gt;, when &lt;EM&gt;O&lt;/EM&gt; become unrooted and there are no other roots&amp;nbsp;for &lt;EM&gt;WR&lt;/EM&gt;, both objects are considered to be dead and will be put into F-reachable queue for finalization(check also check &lt;A href="http://www.msdn.microsoft.com/msdnmag/issues/1100/GCI/default.aspx"&gt;Jeffrey's article&lt;/A&gt;). Since there are no guarantee about order of finalizers (things are a little bit different for critical finalizer),&amp;nbsp;when &lt;EM&gt;O&lt;/EM&gt;'s finalizer is executed, &lt;EM&gt;WR&lt;/EM&gt; may already be finalized. Thus inside &lt;EM&gt;O&lt;/EM&gt;'s finalizer or after &lt;EM&gt;O&lt;/EM&gt; is resurrected, it could call methods on the finalized &lt;EM&gt;WR&lt;/EM&gt;. In the example I mentioned at the beginning, the problem is some object's finalizer is calling &lt;EM&gt;IsAlive&lt;/EM&gt; on its &lt;EM&gt;WeakReference &lt;/EM&gt;field.&lt;/P&gt;
&lt;P&gt;The guideline for finalization says not to use any finalizable field in finalizer, so it's fair for &lt;EM&gt;WeakReference&lt;/EM&gt;'s properties to throw exception if they are called in finalizer. But it might be hard for people to understand why &lt;EM&gt;IsAlive&lt;/EM&gt; needs to throw. After all it's only used to check status and doesn't&amp;nbsp;need to access the tracked object if it's already collected. I think the reasoning is that &lt;EM&gt;IsAlive&lt;/EM&gt; is meant to check whether the underlying &lt;EM&gt;GC handle &lt;/EM&gt;tracks a live object, but if the &lt;EM&gt;GC handle &lt;/EM&gt;is already gone during &lt;EM&gt;WeakReference&lt;/EM&gt;'s finalization, we can't answer the question.&lt;/P&gt;
&lt;P&gt;The most interesting part is to look at history of this design decision. In V1.X, both &lt;EM&gt;IsAlive &lt;/EM&gt;and &lt;EM&gt;get_Target &lt;/EM&gt;property throws exception after the &lt;EM&gt;WeakRerence &lt;/EM&gt;object is finalized; in Beta2 of V2.0, &lt;EM&gt;IsAlive&lt;/EM&gt; still throws, but &lt;EM&gt;get_Target &lt;/EM&gt;won't throw, it will return &lt;EM&gt;null &lt;/EM&gt;after finalization; after Beta2, we made a change so that &lt;EM&gt;IsAlive &lt;/EM&gt;won't throw either, it will return false after finalization. Partly because there are too many people calling &lt;EM&gt;WeakReference.IsAlive &lt;/EM&gt;in finalizers, and it is not a really dangerous thing to do. Note that &lt;EM&gt;WeakReference.set_Target &lt;/EM&gt;always throws after finalization.&lt;/P&gt;
&lt;P&gt;So&amp;nbsp;on CLR V2.0 offical released build, you could safely use &lt;EM&gt;WeakReference &lt;/EM&gt;in finalizer.But&amp;nbsp;it is still good practice not to use&amp;nbsp;finalizable objects in finalizer, including &lt;EM&gt;WeakReference&lt;/EM&gt;.&amp;nbsp;&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=458231" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/yunjin/archive/tags/-NET+programming+gotcha+and+debugging+tips/">.NET programming gotcha and debugging tips</category></item><item><title>Thread, System.Threading.Thread, and !Threads (III)</title><link>http://blogs.msdn.com/b/yunjin/archive/2005/08/30/457756.aspx</link><pubDate>Tue, 30 Aug 2005 19:55:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:457756</guid><dc:creator>Yun Jin</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/yunjin/rsscomments.aspx?WeblogPostID=457756</wfw:commentRss><comments>http://blogs.msdn.com/b/yunjin/archive/2005/08/30/457756.aspx#comments</comments><description>&lt;P&gt;I got email asking me to explain &lt;EM&gt;!Threads&lt;/EM&gt; output in details. I think this is a good question and a good topic for another installment to the series.&lt;/P&gt;
&lt;P&gt;Here is an example I'll use for this post:&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;EM&gt;&lt;FONT size=2&gt;0:055&amp;gt; !threads&lt;BR&gt;ThreadCount: 202&lt;BR&gt;UnstartedThread: 95&lt;BR&gt;BackgroundThread: 1&lt;BR&gt;PendingThread: 0&lt;BR&gt;DeadThread: 47&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PreEmptive&amp;nbsp;&amp;nbsp; GC Alloc&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Lock&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ID&amp;nbsp; ThreadOBJ&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; State&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; GC&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Context&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Domain&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Count APT Exception&lt;BR&gt;&amp;nbsp; 0&amp;nbsp; 0xed0 0x0014f260&amp;nbsp;&amp;nbsp; 0x2000020 Enabled&amp;nbsp; 0x00000000:0x00000000 0x00149aa0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1 Ukn&lt;BR&gt;&amp;nbsp; 1&amp;nbsp; 0xa3c 0x00157d28&amp;nbsp;&amp;nbsp; 0x2001220 Enabled&amp;nbsp; 0x00000000:0x00000000 0x00149aa0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 Ukn (Finalizer)&lt;BR&gt;XXX&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 0x00166378&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x1820 Enabled&amp;nbsp; 0x00000000:0x00000000 0x00149aa0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 Ukn&lt;BR&gt;&amp;nbsp; 4 0x12cc 0x00166540&amp;nbsp;&amp;nbsp; 0x2001020 Enabled&amp;nbsp; 0x00000000:0x00000000 0x00149aa0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 STA&lt;BR&gt;&amp;nbsp; 5 0x12dc 0x00166708&amp;nbsp;&amp;nbsp; 0x2001020 Enabled&amp;nbsp; 0x00000000:0x00000000 0x00149aa0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 Ukn&lt;BR&gt;&amp;nbsp; 3&amp;nbsp; 0xe7c 0x00175b70&amp;nbsp;&amp;nbsp; 0x2001020 Enabled&amp;nbsp; 0x00000000:0x00000000 0x00149aa0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 Ukn&lt;BR&gt;XXX&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 0x00175d38&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x1820 Enabled&amp;nbsp; 0x00000000:0x00000000 0x00149aa0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 Ukn&lt;BR&gt;XXX&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 0x00175f00&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x1820 Enabled&amp;nbsp; 0x00000000:0x00000000 0x00149aa0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 Ukn&lt;BR&gt;XXX&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 0x001760c8&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x1820 Enabled&amp;nbsp; 0x00000000:0x00000000 0x00149aa0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 Ukn&lt;BR&gt;XXX&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 0x00176290&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x1820 Enabled&amp;nbsp; 0x00000000:0x00000000 0x00149aa0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 Ukn System.InvalidOperationException&lt;BR&gt;XXX&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 0x00176458&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x1820 Enabled&amp;nbsp; 0x00000000:0x00000000 0x00149aa0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 Ukn&lt;BR&gt;XXX&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 0x00176620&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x1820 Enabled&amp;nbsp; 0x00000000:0x00000000 0x00149aa0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 Ukn&lt;BR&gt;XXX&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 0x001767e8&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x1820 Enabled&amp;nbsp; 0x00000000:0x00000000 0x00149aa0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 Ukn&lt;BR&gt;&amp;nbsp;12&amp;nbsp; 0x7e0 0x001769b0&amp;nbsp;&amp;nbsp; 0x2001020 Enabled&amp;nbsp; 0x00000000:0x00000000 0x00149aa0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 Ukn&lt;BR&gt;&amp;nbsp;13 0x15e8 0x00178008&amp;nbsp;&amp;nbsp; 0x2001020 Enabled&amp;nbsp; 0x00000000:0x00000000 0x00149aa0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 Ukn&lt;BR&gt;&amp;nbsp;14&amp;nbsp; 0x4d0 0x001781d0&amp;nbsp;&amp;nbsp; 0x2001020 Enabled&amp;nbsp; 0x00000000:0x00000000 0x00149aa0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 Ukn&lt;BR&gt;XXX&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 0x00178398&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x1820 Enabled&amp;nbsp; 0x00000000:0x00000000 0x00149aa0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 Ukn&lt;BR&gt;XXX&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 0x00178560&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x1820 Enabled&amp;nbsp; 0x00000000:0x00000000 0x00149aa0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 Ukn&lt;BR&gt;XXX&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 0x00178728&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x1820 Enabled&amp;nbsp; 0x00000000:0x00000000 0x00149aa0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 Ukn&lt;BR&gt;XXX&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 0x001788f0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x1820 Enabled&amp;nbsp; 0x00000000:0x00000000 0x00149aa0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 Ukn&lt;BR&gt;XXX&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 0x00178ab8&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x1820 Enabled&amp;nbsp; 0x00000000:0x00000000 0x00149aa0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 Ukn&lt;BR&gt;XXX&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 0x00178c80&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x1820 Enabled&amp;nbsp; 0x00000000:0x00000000 0x00149aa0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 Ukn&lt;BR&gt;XXX&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 0x00178e48&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x1820 Enabled&amp;nbsp; 0x00000000:0x00000000 0x00149aa0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 Ukn&lt;BR&gt;&amp;nbsp;21 0x14f0 0x00179010&amp;nbsp;&amp;nbsp; 0x2001020 Enabled&amp;nbsp; 0x00000000:0x00000000 0x00149aa0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 Ukn&lt;BR&gt;&amp;nbsp;22 0x1708 0x001791d8&amp;nbsp;&amp;nbsp; 0x2001020 Enabled&amp;nbsp; 0x00000000:0x00000000 0x00149aa0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 Ukn&lt;BR&gt;&amp;nbsp;23 0x11f8 0x001793a0&amp;nbsp;&amp;nbsp; 0x2001020 Enabled&amp;nbsp; 0x00000000:0x00000000 0x00149aa0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 Ukn&lt;BR&gt;&amp;nbsp;24&amp;nbsp; 0x224 0x00179568&amp;nbsp;&amp;nbsp; 0x2001020 Enabled&amp;nbsp; 0x00000000:0x00000000 0x00149aa0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 Ukn&lt;BR&gt;XXX&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 0x00179730&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x1820 Enabled&amp;nbsp; 0x00000000:0x00000000 0x00149aa0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 Ukn&lt;BR&gt;XXX&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 0x001798f8&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x1820 Enabled&amp;nbsp; 0x00000000:0x00000000 0x00149aa0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 Ukn&lt;BR&gt;XXX&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 0x00179ac0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x1820 Enabled&amp;nbsp; 0x00000000:0x00000000 0x00149aa0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 Ukn System.InvalidOperationException&lt;BR&gt;XXX&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 0x00179c88&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x1820 Enabled&amp;nbsp; 0x00000000:0x00000000 0x00149aa0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 Ukn System.InvalidOperationException&lt;BR&gt;XXX&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 0x00179e50&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x1820 Enabled&amp;nbsp; 0x00000000:0x00000000 0x00149aa0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 Ukn&lt;BR&gt;...&lt;/FONT&gt;&lt;/EM&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;STRONG&gt;First &lt;EM&gt;!Threads&lt;/EM&gt; gives some statistics about &lt;EM&gt;Thread Store&lt;/EM&gt;.&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;ThreadCount&lt;/EM&gt;: number of total &lt;EM&gt;C++ Thread&lt;/EM&gt; objects in &lt;EM&gt;Thread Store&lt;/EM&gt;.&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;UnstartedThread&lt;/EM&gt;: number of &lt;EM&gt;C++ Thread&lt;/EM&gt; objects marked as unstarted. Recall I mentioned in &lt;A href="http://http://blogs.msdn.com/yunjin/archive/2005/08/25/456355.aspx"&gt;previous blog&lt;/A&gt;, if a user creates a &lt;EM&gt;C# Thread&lt;/EM&gt; object, CLR will create an "unstarted" &lt;EM&gt;C++ Thread&lt;/EM&gt; object. When &lt;EM&gt;Thread.Start&lt;/EM&gt; is called on the C# object, CLR will create an &lt;EM&gt;OS thread&lt;/EM&gt; and remove "unstarted" flag from the &lt;EM&gt;C++ Thread&lt;/EM&gt; object.&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;BackgroundThread&lt;/EM&gt;: number of &lt;EM&gt;C++ Threads&lt;/EM&gt; (and the corresponding &lt;EM&gt;OS threads&lt;/EM&gt;) considered as background. Being background simply means CLR won't wait the thread for shutting down. Threads created explicitly by using &lt;EM&gt;System.Threading.Thread.Start&lt;/EM&gt; are by default foreground threads; whereas threads wandering into CLR from unmanaged world are by default background threads (Rotor: &lt;EM&gt;SetupThread&lt;/EM&gt; in&lt;EM&gt; vm/threads.cpp&lt;/EM&gt; calls &lt;EM&gt;SetBackground(TRUE)&lt;/EM&gt;). However, whether a thread is background could be changed by using&amp;nbsp;&lt;EM&gt;IsBackground&lt;/EM&gt; property in &lt;EM&gt;C# Thread&lt;/EM&gt; object.&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;PendingThreads&lt;/EM&gt;: If an &lt;EM&gt;OS thread&lt;/EM&gt; is created but its &lt;EM&gt;ThreadProc&lt;/EM&gt; hasn't be executed to the place to decrement unstarted counter in &lt;EM&gt;Thread Store&lt;/EM&gt;, the thread is considered&amp;nbsp;to be pending. Number of this type of threads should be quite low.&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;DeadThreads&lt;/EM&gt;: Number of &lt;EM&gt;C++ Thread&lt;/EM&gt; objects whose &lt;EM&gt;OS threads&lt;/EM&gt; are already dead but the &lt;EM&gt;C++ objects&lt;/EM&gt; themselves are not deleted yet.&lt;/P&gt;
&lt;P&gt;In Rotor, all the five numbers are actually stored in &lt;EM&gt;ThreadStore (vm/threads.h)&lt;/EM&gt; object as its fields.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Then it comes a table of all &lt;EM&gt;C++ Thread&lt;/EM&gt; objects in Thread Store. Let me explain each field.&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;The first column doesn't have a header. It is the &lt;EM&gt;OS thread&lt;/EM&gt; ID given by debugger just for debugging readability. Because the numbers only exist in debugger process, not the debuggee process, you may see the number being different when you look at a live session than when you debug a dump taken from the same live session. For a "dead"&amp;nbsp;or "unstarted" thread, this column is "XXX".&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;ID&lt;/EM&gt;: this is the thread ID assigned by OS, it remains consistent during debugger sessions, but OS could recycle it.&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;ThreadOBJ&lt;/EM&gt;: address of &lt;EM&gt;C++ Thread&lt;/EM&gt; object. You could see contents of the object by &lt;EM&gt;"dt mscorwks!Thread &amp;lt;address&amp;gt;"&lt;/EM&gt; if you have symbols for mscorwks.dll.&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;State&lt;/EM&gt;: one of the most important fields of the table. For Rotor, it is the &lt;EM&gt;C++ Thread's m_State&lt;/EM&gt; field.&amp;nbsp; It is combination of&amp;nbsp;bit masks&amp;nbsp;to indicate what the status the &lt;EM&gt;Thread&lt;/EM&gt; currently is. All possible states (bit masks)&amp;nbsp;are defined as enum &lt;EM&gt;ThreadState&lt;/EM&gt; in &lt;EM&gt;vm/Threads&lt;/EM&gt;. We already covered several states like &lt;EM&gt;TS_Background&lt;/EM&gt;, &lt;EM&gt;TS_Unstarted&lt;/EM&gt;, and &lt;EM&gt;TS_Dead&lt;/EM&gt;. More states include &lt;EM&gt;TS_AbortRequested&lt;/EM&gt; (this thread is requested to be aborted), &lt;EM&gt;TS_AbortInitiated&lt;/EM&gt; (abort process is already started for this thread), &lt;EM&gt;TS_GCSuspendPending&lt;/EM&gt; (GC is trying to suspend this thread), and etc.&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;Preemptive GC&lt;/EM&gt;: also very important. In Rotor, this is &lt;EM&gt;m_fPreemptiveGCDisabled&lt;/EM&gt; field of&lt;EM&gt; C++ Thread&lt;/EM&gt; class. It indicates what GC mode the thread is in: "enabled" in the table means the thread is in &lt;EM&gt;preemptive mode&lt;/EM&gt; where GC could preempt this thread at any time; "disabled" means the thread is in cooperative mode where GC has to wait the thread to give up its current work (the work is related to GC objects so it can't allow GC to move the objects around). When the thread is executing managed code (the current IP is in managed code), it is always in cooperative mode; when the thread is in &lt;EM&gt;Execution Engine&lt;/EM&gt; (unmanaged code), &lt;EM&gt;EE &lt;/EM&gt;code could choose to stay in either mode and could switch mode at any time; when a thread are outside of CLR (e.g, calling into native code using interop), it is always in preemptive mode.&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;GC Alloc context&lt;/EM&gt;: allocate context GC might use when it tries to allocate object for this thread. In Rotor, it is &lt;EM&gt;m_alloc_context&lt;/EM&gt; in &lt;EM&gt;C++ Thread&lt;/EM&gt; object. &lt;/P&gt;
&lt;P&gt;&lt;EM&gt;Domain&lt;/EM&gt;: which &lt;EM&gt;AppDomain&lt;/EM&gt; the thread is currently in (Rotor:&lt;EM&gt; m_pDomain&lt;/EM&gt; field of &lt;EM&gt;C++ Thread&lt;/EM&gt; class). You could use &lt;EM&gt;!DumpDomain&lt;/EM&gt; or "dt mscorwks!AppDomain" to dump details of the domain. A thread can only be in one domain at a time, but it could switch into different domains. Speical marks will be put on thread's stack to when it transit to another domain.&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;Lock count&lt;/EM&gt;: how many locks this thread has taken (Rotor: &lt;EM&gt;m_dwLockCount&lt;/EM&gt; field of &lt;EM&gt;C++ Thread&lt;/EM&gt; class). The locks it tracks include the managed monitors (taken by &lt;EM&gt;lock(obj)&lt;/EM&gt; in C#),&amp;nbsp;BCL's &lt;EM&gt;ReaderWriterLock&lt;/EM&gt;, and certain locks inside CLR's unmanaged code.&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;APT&lt;/EM&gt;: &lt;EM&gt;COM&lt;/EM&gt; apartment for the thread, whether the thread is in a single-threaded apartment (&lt;EM&gt;STA&lt;/EM&gt;), multithreaded apartment(&lt;EM&gt;MTA&lt;/EM&gt;) or unknown.&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;Exception&lt;/EM&gt;: the last managed exception thrown from this thread. It is saved in a GC handle in the &lt;EM&gt;C++ Thread&lt;/EM&gt; object (Rotor: &lt;EM&gt;m_LastThrownObjectHandle&lt;/EM&gt;).&lt;/P&gt;
&lt;P&gt;The last column also indicates which &lt;a href="http://blogs.msdn.com/yunjin/archive/2005/07/05/435726.aspx"&gt;special thread &lt;/A&gt;this thread is. However,&amp;nbsp;&lt;EM&gt;!Threads&lt;/EM&gt; only recognize&amp;nbsp;a limited type of special threads for this field, including &lt;EM&gt;Finalizer thread&lt;/EM&gt;, &lt;EM&gt;GC thread&lt;/EM&gt;, &lt;EM&gt;Threadpool Worker thread&lt;/EM&gt;, and &lt;EM&gt;Threadpool Completion Port thread&lt;/EM&gt;. And for special threads which doesn't have a &lt;EM&gt;C++ Thread &lt;/EM&gt;object (a special thread doesn't need to run managed code like debugger helper thread and server GC thread), they&amp;nbsp;can not be displayed here. In Whidbey, a "&lt;EM&gt;-special&lt;/EM&gt;" option is added to &lt;EM&gt;!Threads &lt;/EM&gt;command which will show all special threads in the process as a separate list. Here is a sample output:&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;EM&gt;&lt;FONT size=2&gt;0:007&amp;gt; !threads -special&lt;BR&gt;ThreadCount: 4&lt;BR&gt;UnstartedThread: 0&lt;BR&gt;BackgroundThread: 3&lt;BR&gt;PendingThread: 0&lt;BR&gt;DeadThread: 0&lt;BR&gt;Hosted Runtime: no&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PreEmptive&amp;nbsp;&amp;nbsp; GC Alloc&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Lock&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ID OSID ThreadOBJ&amp;nbsp;&amp;nbsp;&amp;nbsp; State&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; GC&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Context&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Domain&amp;nbsp;&amp;nbsp; Count APT Exception&lt;BR&gt;&amp;nbsp;&amp;nbsp; 0&amp;nbsp;&amp;nbsp;&amp;nbsp; 1&amp;nbsp; 828 0029a030&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; a020 Disabled 06907c38:069081d4 0f59e038&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2 MTA&lt;BR&gt;&amp;nbsp;&amp;nbsp; 4&amp;nbsp;&amp;nbsp;&amp;nbsp; 2 16fc 0029e980&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; b220 Enabled&amp;nbsp; 0690424c:069061d4 0021f4a8&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 MTA (Finalizer)&lt;BR&gt;&amp;nbsp;&amp;nbsp; 5&amp;nbsp;&amp;nbsp;&amp;nbsp; 3 1c1c 002e71e8&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1220 Enabled&amp;nbsp; 028f20f8:028f3f94 0021f4a8&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 Ukn&lt;BR&gt;&amp;nbsp;&amp;nbsp; 6&amp;nbsp;&amp;nbsp;&amp;nbsp; 4 1244 0f6fa778&amp;nbsp;&amp;nbsp;&amp;nbsp; 80a220 Enabled&amp;nbsp; 00000000:00000000 0021f4a8&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 MTA (Threadpool Completion Port)&lt;/FONT&gt;&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;&lt;FONT size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; OSID&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Special thread type&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1&amp;nbsp;&amp;nbsp;&amp;nbsp; e20&amp;nbsp;&amp;nbsp;&amp;nbsp; DbgHelper &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2&amp;nbsp;&amp;nbsp; 1e1c&amp;nbsp;&amp;nbsp;&amp;nbsp; GC &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3&amp;nbsp;&amp;nbsp; 1ed4&amp;nbsp;&amp;nbsp;&amp;nbsp; GC &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 4&amp;nbsp;&amp;nbsp; 16fc&amp;nbsp;&amp;nbsp;&amp;nbsp; Finalizer &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 5&amp;nbsp;&amp;nbsp; 1c1c&amp;nbsp;&amp;nbsp;&amp;nbsp; ADUnloadHelper &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 6&amp;nbsp;&amp;nbsp; 1244&amp;nbsp;&amp;nbsp;&amp;nbsp; Timer&lt;/FONT&gt;&lt;/EM&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;This posting is provided "AS IS" with no warranties, and confers no rights.&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=457756" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/yunjin/archive/tags/Rotor+code+explanation/">Rotor code explanation</category><category domain="http://blogs.msdn.com/b/yunjin/archive/tags/-NET+programming+gotcha+and+debugging+tips/">.NET programming gotcha and debugging tips</category><category domain="http://blogs.msdn.com/b/yunjin/archive/tags/CLR+internal+and+Misc/">CLR internal and Misc</category></item></channel></rss>