<?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>PFE - Developer Notes for the Field : Fabrice</title><link>http://blogs.msdn.com/pfedev/archive/tags/Fabrice/default.aspx</link><description>Tags: Fabrice</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Best Practice - Workflow and Anonymous Delegates</title><link>http://blogs.msdn.com/pfedev/archive/2009/03/23/best-practice-workflow-and-anonymous-delegates.aspx</link><pubDate>Mon, 23 Mar 2009 07:35:49 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9500520</guid><dc:creator>pfedevblog</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/pfedev/comments/9500520.aspx</comments><wfw:commentRss>http://blogs.msdn.com/pfedev/commentrss.aspx?PostID=9500520</wfw:commentRss><description>&lt;h1&gt;Best Practice Recommendation&lt;/h1&gt;  &lt;p&gt;In your Workflow application (more exactly in the host of your workflow application) &lt;b&gt;never&lt;/b&gt; use anonymous delegate like that :&lt;/p&gt;  &lt;pre class="csharpcode"&gt;                  AutoResetEvent waitHandle = &lt;span class="kwrd"&gt;new&lt;/span&gt; AutoResetEvent(&lt;span class="kwrd"&gt;false&lt;/span&gt;);
                  .
                  .
                  .

                  workflowRuntime.WorkflowTerminated += &lt;span class="kwrd"&gt;delegate&lt;/span&gt;(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, WorkflowTerminatedEventArgs e)
                  {
                            waitHandle.Set();
                  };&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;h1&gt;Details&lt;/h1&gt;

&lt;p&gt;The code above is very common and works correctly at least most of the time... Actually when you do something like that, then after a few iterations (if you always keep the same instance of the Workflow runtime as it should be the case) you will notice the number of AutoResetEvent object always increases until eventually an Out Of Memory exception is raised.&lt;/p&gt;

&lt;p&gt;If you take a debugger like Windbg and display the chain of reference for one particular instance of the AutoResetEvent class you will have an output similar to the following:&lt;/p&gt;

&lt;p&gt;&lt;font face="Courier New"&gt;DOMAIN(00000000002FF7E0):HANDLE(WeakSh):c1580:Root:&amp;#160; 00000000029126e8(System.Workflow.Runtime.WorkflowRuntime)-&amp;gt; 
    &lt;br /&gt;&amp;#160; 000000000296e500(System.EventHandler`1[[System.Workflow.Runtime.WorkflowTerminatedEventArgs, System.Workflow.Runtime]])-&amp;gt; 

    &lt;br /&gt;&amp;#160; 0000000002966970(System.Object[])-&amp;gt;&amp;#160; 00000000029570e0(System.EventHandler`1[[System.Workflow.Runtime.WorkflowTerminatedEventArgs, System.Workflow.Runtime]])-&amp;gt; 

    &lt;br /&gt;&amp;#160; 0000000002957038&lt;b&gt;(TestLeakWorkflow.Program+&amp;lt;&amp;gt;c__DisplayClass2)&lt;/b&gt;-&amp;gt;&amp;#160; 0000000002957050(System.Threading.AutoResetEvent)&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;If now you dump the instance of TestLeakWorkflow.Program+&amp;lt;&amp;gt;c__DisplayClass2 you will have the following output : &lt;/p&gt;

&lt;p&gt;&lt;font face="Courier New"&gt;MT&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Field&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Offset&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Type&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; VT&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Attr&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Value&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Name
    &lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;000007fef70142d0&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 4000003&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 8&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; AutoResetEvent&amp;#160;&amp;#160;&amp;#160;&amp;#160; 0&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; instance&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 0000000002957050&amp;#160;&amp;#160;&amp;#160; waitHandle&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;What does it tell us? This class TestLeakWorkflow.Program+&amp;lt;&amp;gt;c__DisplayClass2 contains one property of type AutoResetEvent. In our case this property has a strong reference to the object of type AutoResetEvent, consequently the final object is still referenced and remains logically memory.&lt;/p&gt;

&lt;p&gt;Why that? Well the purpose of this entry is not to give details about anonymous delegate, but basically there is nothing magic with anonymous delegate, and for the delegate function to access to variable which are not in its scope (look closer, the waitHandle object is not in the scope of the delegate function but still it can access to it) a mechanism is needed. For that, the compiler creates an intermediate class with one property per object which is used in the function delegate but which is normally not in its scope, the delegate function is just a member function of this class; it can then easily access to the properties of the class. &lt;/p&gt;

&lt;p&gt;What if you use hundred of objects in the anonymous delegate, objects which are normally not in the scope of the delegate? Well, you will have an intermediate class with hundred of attributes. The instances of the class will then reference the real objects...&lt;/p&gt;

&lt;p&gt;Why is that a problem? Well, again look closely? How can you get rid of this instance? You have to remove the reference to the delegate but you cannot (not with the syntax used above), it means the intermediary class and more problematically the final object are still referenced and remain in memory.&lt;/p&gt;

&lt;p&gt;To better understand the problem, let’s now study the fragment below, this is a quite classical fragment of code that you will often find in multiple blogs (I know it’s from one of this blog that we have got the code that have been implanted in production and on which I have spent hours debugging to understand why the portal was dying after several hours) :&lt;/p&gt;

&lt;pre class="csharpcode"&gt;        WorkflowInstance instance = workflowRuntime.CreateWorkflow(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(MyASPNetSequencialWorkFlow));

        instance.Start();

        workflowRuntime.WorkflowCompleted += &lt;span class="kwrd"&gt;delegate&lt;/span&gt;(&lt;span class="kwrd"&gt;object&lt;/span&gt; o, WorkflowCompletedEventArgs e1)
        {
&lt;span class="kwrd"&gt;            if&lt;/span&gt; (e1.WorkflowInstance.InstanceId == instance.InstanceId)
            { ...&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;Yes you got it, in this case this is the Workflow instance which will be referenced and which will stay in memory. Considering the fact that in a web application host (as well as in Windows service host) the WorkflowRuntime is a long live object, you will for sure have an Out Of Memory exception.&lt;/p&gt;

&lt;p&gt;What do then? Well a code like the one below is definitely better :&lt;/p&gt;

&lt;pre class="csharpcode"&gt;                    EventHandler&amp;lt;WorkflowTerminatedEventArgs&amp;gt; terminatedHandler = &lt;span class="kwrd"&gt;null&lt;/span&gt;;
                    EventHandler&amp;lt;WorkflowCompletedEventArgs&amp;gt; completedHandler = &lt;span class="kwrd"&gt;null&lt;/span&gt;;

                    terminatedHandler = &lt;span class="kwrd"&gt;delegate&lt;/span&gt;(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, WorkflowTerminatedEventArgs e)
                    {
&lt;span class="kwrd"&gt;                        if&lt;/span&gt; (instance.InstanceId == e.WorkflowInstance.InstanceId)
                        {
                            Console.WriteLine(e.Exception.Message);
                            workflowRuntime.WorkflowCompleted -= completedHandler;
                            workflowRuntime.WorkflowTerminated -= terminatedHandler;
                            waitHandle.Set();
                        }
                    };

                    workflowRuntime.WorkflowTerminated += terminatedHandler;
&lt;br /&gt;                    completedHandler = &lt;span class="kwrd"&gt;delegate&lt;/span&gt;(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, WorkflowCompletedEventArgs e)
                    {
&lt;span class="kwrd"&gt;                        if&lt;/span&gt; (instance.InstanceId == e.WorkflowInstance.InstanceId)
                        {
                            WorkflowInstance b = instance;
                            workflowRuntime.WorkflowCompleted -= completedHandler;
                            workflowRuntime.WorkflowTerminated -= terminatedHandler;
                            waitHandle.Set();
                        }
                    };

                    workflowRuntime.WorkflowCompleted += completedHandler;&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;You again have to be prudent, you must remove all the handlers, if at the end WorkflowCompleted Handler is executed, WorkflowTerminated handler will never be executed hence the all the handler are removed in both delegates.&lt;/p&gt;

&lt;p&gt;Thanks,
  &lt;br /&gt;Fabrice&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9500520" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/pfedev/archive/tags/.NET/default.aspx">.NET</category><category domain="http://blogs.msdn.com/pfedev/archive/tags/Best+Practice/default.aspx">Best Practice</category><category domain="http://blogs.msdn.com/pfedev/archive/tags/Fabrice/default.aspx">Fabrice</category><category domain="http://blogs.msdn.com/pfedev/archive/tags/Workflow/default.aspx">Workflow</category></item><item><title>Best Practice – WCF and Exceptions</title><link>http://blogs.msdn.com/pfedev/archive/2008/12/04/best-practice-wcf-and-exceptions.aspx</link><pubDate>Thu, 04 Dec 2008 20:27:49 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9175862</guid><dc:creator>pfedevblog</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/pfedev/comments/9175862.aspx</comments><wfw:commentRss>http://blogs.msdn.com/pfedev/commentrss.aspx?PostID=9175862</wfw:commentRss><description>&lt;h1&gt;Best Practice Recommendation&lt;/h1&gt;  &lt;p&gt;In your WCF service, never let an exception propagate outside the service boundary without managing it. 2 Alternatives then :&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Either you manage the exception inside the service boundary and never propagate it outside &lt;/li&gt;    &lt;li&gt;Or you convert the .Net typed exception in your exception manager as a FaultException before propagating it. &lt;/li&gt; &lt;/ul&gt;  &lt;h1&gt;Details&lt;/h1&gt;  &lt;p&gt;Most of the developers know how to handle exception in .Net code and good strategy can consist in letting an exception bubble up if it cannot be handled correctly, ultimately this exception will be managed by one of the .Net framework default handler which can depending of the situation close the application.&lt;/p&gt;  &lt;p&gt;WCF manages things slightly differently, indeed if the developer let an exception bubbles up to the WCF default handler, it will convert this .Net typed exception (which has no representation in the SOA world) as a Fault Exception (which is represented in the SOA world as a SOAP fault &lt;a href="http://www.w3.org/TR/soap12-part1/"&gt;http://www.w3.org/TR/soap12-part1/&lt;/a&gt; ) and then propagate this exception to the client. Up to this point, you think everything is OK, and you are right indeed it’s legitimate the client application receives the exception and manages it. However there are 2 problems here :&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;One minor, indeed by default you don’t control the conversion, and you may want to send a custom Fault Exception to the client application, something not too generic. &lt;/li&gt;    &lt;li&gt;The WCF default handler will fault the channel and this is far more problematic because if the client reuse the proxy (what is a quite common approach after managing the exception), it will fail. It’s quite easy in .Net to work around this issue just by testing if the proxy is faulted in the exception manager but all the languages may not offer these facilities and I remind you by essence SOA is very opened. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;For those of you who wants more information this blog is very good : &lt;a href="http://weblogs.asp.net/pglavich/archive/2008/10/16/wcf-ierrorhandler-and-propagating-faults.aspx"&gt;http://weblogs.asp.net/pglavich/archive/2008/10/16/wcf-ierrorhandler-and-propagating-faults.aspx&lt;/a&gt; from a general point of view, the implementation of IErrorHandler is a popular approach to handle this issue so from your favorite search engine (&lt;a href="http://www.live.com"&gt;www.live.com&lt;/a&gt;) just search for IErrorhandler.&lt;/p&gt;  &lt;p&gt;Contributed by Fabrice Aubert&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9175862" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/pfedev/archive/tags/.NET/default.aspx">.NET</category><category domain="http://blogs.msdn.com/pfedev/archive/tags/Best+Practice/default.aspx">Best Practice</category><category domain="http://blogs.msdn.com/pfedev/archive/tags/Fabrice/default.aspx">Fabrice</category></item></channel></rss>