<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://msmvps.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>Omar AL Zabir blog on ASP.NET Ajax and .NET 3.5 : linq</title><link>http://msmvps.com/blogs/omar/archive/tags/linq/default.aspx</link><description>Tags: linq</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP2 (Build: 40407.4157)</generator><item><title>Simple way to cache objects and collections for greater performance and scalability</title><link>http://msmvps.com/blogs/omar/archive/2009/11/01/simple-way-to-cache-objects-and-collections-for-greater-performance-and-scalability.aspx</link><pubDate>Sun, 01 Nov 2009 16:41:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1736807</guid><dc:creator>omar</dc:creator><slash:comments>7</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/omar/rsscomments.aspx?PostID=1736807</wfw:commentRss><comments>http://msmvps.com/blogs/omar/archive/2009/11/01/simple-way-to-cache-objects-and-collections-for-greater-performance-and-scalability.aspx#comments</comments><description>&lt;p&gt;Caching of frequently used data greatly increases the scalability of your application since you can avoid repeated queries on database, file system or to webservices. When objects are cached, it can be retrieved from the cache which is lot faster and more scalable than loading from database, file or web service. However, implementing caching is tricky and monotonous when you have to do it for many classes. Your data access layer gets a whole lot of code that deals with caching objects and collection, updating cache when objects change or get deleted, expire collections when a contained object changes or gets deleted and so on. The more code you write, the more maintenance overhead you add. Here I will show you how you can make the caching a lot easier using Linq to SQL and my library &lt;a title="Fluent way to add Aspect in your code" href="http://code.google.com/p/aspectf/"&gt;AspectF&lt;/a&gt;. It’s a library that helps you get rid of thousands of lines of repeated code from a medium sized project and eliminates plumbing (logging, error handling, retrying etc) type code completely.&lt;/p&gt;  &lt;p&gt;Here’s an example how caching significantly improves the performance and scalabitlity of applications. Dropthings – my open source Web 2.0 AJAX portal, without caching can only serve about 11 request/sec with 10 concurrent users on a dual core 64 bit PC. Here data is loaded from database as well as from external sources. Avg page response time is 1.44 sec.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar.metablogapi/4606.LoadTestWithoutCache_5F00_507E9888.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="Load Test Without Cache" border="0" alt="Load Test Without Cache" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar.metablogapi/0003.LoadTestWithoutCache_5F00_thumb_5F00_4D790E08.png" width="557" height="364" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;After implementing caching, it became significantly faster, around &lt;strong&gt;32 requests/sec&lt;/strong&gt;. Page load time decreased significantly as well to &lt;strong&gt;0.41 sec&lt;/strong&gt; only. During the load test, CPU utilization was around 60%.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar.metablogapi/0410.LoadTestwithinmemorycache_5F00_33E15B0E.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="Load Test with in memory cache" border="0" alt="Load Test with in memory cache" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar.metablogapi/6761.LoadTestwithinmemorycache_5F00_thumb_5F00_7F6088C5.png" width="598" height="411" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;It shows clearly the significant difference it can make to your application. If you are suffering from poor page load performance and high CPU or disk activity on your database and application server, then caching Top 5 most frequently used objects in your application will solve that problem right away. It’s a quick win to make your application a lot faster than doing complex re-engineering in your application.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Common approaches to caching objects and collections&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Sometimes the caching can be simple, for example caching a single object which does not belong to a collection and does not have child collections that are cached separately. In such case, you write simple code like this:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Is the object being requested already in cache?      &lt;ul&gt;       &lt;li&gt;Yes, then serve it from cache. &lt;/li&gt;        &lt;li&gt;No, then load it from database and then cache it. &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;On the other hand, when you are dealing with cached collection where each item in the collection is also cached separately, then the caching logic is not so simple. For example, say you have cached a &lt;code&gt;User&lt;/code&gt; collection. But each &lt;code&gt;User&lt;/code&gt; object is also cached separately because you need to load individual &lt;code&gt;User&lt;/code&gt; objects frequently. Then the caching logic gets more complicated:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Is the collection being requested already in cache?      &lt;ul&gt;       &lt;li&gt;Yes. Get the collection. For each object in the collection:          &lt;ul&gt;           &lt;li&gt;Is that object individually available in cache?              &lt;ul&gt;               &lt;li&gt;Yes, get the individual object from cache. Update it in the collection. &lt;/li&gt;                &lt;li&gt;No, discard the whole collection from cache. Go to next step: &lt;/li&gt;             &lt;/ul&gt;           &lt;/li&gt;         &lt;/ul&gt;       &lt;/li&gt;        &lt;li&gt;No. Load the collection from source (eg database) and cache each item in the collection separately. Then cache the collection. &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;You might be thinking why do we need to read each individual item from cache and why do we need to cache each item in collection separarely when the whole collection is already in cache? There are two scenarios you need to address when you cache a collection and individual items in that collection are also cached separately:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;An individual item has been updated and the updated item is in cache. But the collection, which contains all those individual items, has not been refreshed. So, if you get the collection from cache and return as it is, you will get stale individual items inside that collection. This is why each item needs to be retrieved from cache separately. &lt;/li&gt;    &lt;li&gt;An item in the collection may have been force expired in cache. For ex, something changed in the object or the object has been deleted. So, you expired it in cache so that on next retrieval it comes from database. If you load the collection from cache only, then the collection will contain the stale object. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;If you are doing it the conventional way, you will be writing a lot of repeated code in your data access layer. For example, say you are loading a &lt;code&gt;Page&lt;/code&gt; collection that belongs to a user. If you want to cache the collection of &lt;code&gt;Page&lt;/code&gt; for a user as well as cache individual &lt;code&gt;Page&lt;/code&gt; objects so that each &lt;code&gt;Page&lt;/code&gt; can be retrieved from Cache directly. Then you need to write code like this:&lt;/p&gt;  &lt;pre class="dark"&gt;&lt;span style="background:#2a2a2a;color:#eaeaac;"&gt;public &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#f0dfaf;"&gt;List&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#f0dfaf;"&gt;Page&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;&amp;gt; &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;GetPagesOfUserOldSchool&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#2b91af;"&gt;Guid &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;userGuid&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;)
{
    &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#2b91af;"&gt;ICache &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;cache &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#f0dfaf;"&gt;Services&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;Get&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#2b91af;"&gt;ICache&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;&amp;gt;();
    &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#eaeaac;"&gt;bool &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;isCacheStale &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#eaeaac;"&gt;false&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;;
    &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#eaeaac;"&gt;string &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;cacheKey &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#f0dfaf;"&gt;CacheSetup&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#f0dfaf;"&gt;CacheKeys&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;PagesOfUser&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;userGuid&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;);
    &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#eaeaac;"&gt;var &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;cachedPages &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;cache&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;Get&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;cacheKey&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;) &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#eaeaac;"&gt;as &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#f0dfaf;"&gt;List&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#f0dfaf;"&gt;Page&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;&amp;gt;;
    &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#eaeaac;"&gt;if &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;cachedPages &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;!= &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#eaeaac;"&gt;null&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;)
    {
        &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#eaeaac;"&gt;var &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;resultantPages &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#eaeaac;"&gt;new &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#f0dfaf;"&gt;List&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#f0dfaf;"&gt;Page&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;&amp;gt;();
        &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#7f9f7f;"&gt;// If each item in the collection is no longer in cache, invalidate the collection
        // and load again.
        &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#eaeaac;"&gt;foreach &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#f0dfaf;"&gt;Page &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;cachedPage &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#eaeaac;"&gt;in &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;cachedPages&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;)
        {
            &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#eaeaac;"&gt;var &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;individualPageInCache &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;cache&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;Get&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#f0dfaf;"&gt;CacheSetup&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#f0dfaf;"&gt;CacheKeys&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;PageId&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;cachedPage&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;ID&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;)) &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#eaeaac;"&gt;as &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#f0dfaf;"&gt;Page&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;;
            &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#eaeaac;"&gt;if &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#eaeaac;"&gt;null &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;== &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;individualPageInCache&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;)
            {
                &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#7f9f7f;"&gt;// Some item is missing in cache. So, the collection is stale. 
                &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;isCacheStale &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#eaeaac;"&gt;true&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;;
            }
            &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#eaeaac;"&gt;else
            &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;{
                &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;resultantPages&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;Add&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;individualPageInCache&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;);
            }
        }

        &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;cachedPages &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;resultantPages&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;;
    }

    &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#eaeaac;"&gt;if &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;isCacheStale&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;)
    {
        &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#7f9f7f;"&gt;// Collection not cached. Need to load collection from database and then cache it.
        &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#eaeaac;"&gt;var &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;pagesOfUser &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;_database&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;GetList&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#f0dfaf;"&gt;Page&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;, &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#2b91af;"&gt;Guid&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;&amp;gt;(...&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;);
        &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;pagesOfUser&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;Each&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;page &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;=&amp;gt;
        {
            &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;page&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;Detach&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;();
            &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;cache&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;Add&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#f0dfaf;"&gt;CacheSetup&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#f0dfaf;"&gt;CacheKeys&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;PageId&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;page&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;ID&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;), &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;page&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;);
        });
        &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;cache&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;Add&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;cacheKey&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;, &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;pagesOfUser&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;);
        &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#eaeaac;"&gt;return &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;pagesOfUser&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;;
    }
    &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#eaeaac;"&gt;else
    &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;{
        &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#eaeaac;"&gt;return &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;cachedPages&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;;
    }
}&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Imagine writing this kind of code over and over again for each and every entity that you want to cache. This becomes a maintenace nightmare as your project grows.&lt;/p&gt;

&lt;p&gt;Here’s how you could do it using &lt;a title="Fluent way to add Aspect in your code" href="http://code.google.com/p/aspectf/"&gt;AspectF&lt;/a&gt;:&lt;/p&gt;

&lt;pre class="dark"&gt;&lt;span style="background:#2a2a2a;color:#eaeaac;"&gt;public &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#f0dfaf;"&gt;List&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#f0dfaf;"&gt;Page&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;&amp;gt; &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;GetPagesOfUser&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#2b91af;"&gt;Guid &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;userGuid&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;)
{
    &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#eaeaac;"&gt;return &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#f0dfaf;"&gt;AspectF&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;Define
        &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;CacheList&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#f0dfaf;"&gt;Page&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;, &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#f0dfaf;"&gt;List&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#f0dfaf;"&gt;Page&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;&amp;gt;&amp;gt;(&lt;span style="background:#2a2a2a;color:#f0dfaf;"&gt;Services&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;Get&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#2b91af;"&gt;ICache&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;&amp;gt;()&lt;/span&gt;&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;, &lt;br /&gt;&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#f0dfaf;"&gt;                     CacheSetup&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#f0dfaf;"&gt;CacheKeys&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;PagesOfUser&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;userGuid&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;), &lt;br /&gt;&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;                     page &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;=&amp;gt; &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#f0dfaf;"&gt;CacheSetup&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#f0dfaf;"&gt;CacheKeys&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;PageId&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;page&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;ID&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;))
        .&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;Return&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#f0dfaf;"&gt;List&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#f0dfaf;"&gt;Page&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;&amp;gt;&amp;gt;(() =&amp;gt; 
            &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;_database&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;GetList&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#f0dfaf;"&gt;Page&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;, &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#2b91af;"&gt;Guid&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;&amp;gt;(&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#f0dfaf;"&gt;...&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;).&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;Select&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;p &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;=&amp;gt; &lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;p&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;Detach&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;()).&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dfdfbf;"&gt;ToList&lt;/span&gt;&lt;span style="background:#2a2a2a;color:#dcdccc;"&gt;());
}
&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Instead of 42 lines of code, you can do it in 5 lines!&lt;/p&gt;

&lt;p&gt;Read my article &lt;a title="Simple way to cache objects and collections for greater performance and scalability" href="http://www.codeproject.com/KB/web-cache/easycaching.aspx"&gt;Simple way to cache objects and collections for greater performance and scalability&lt;/a&gt; on CodeProject and learn:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Caching Linq to SQL entities &lt;/li&gt;

  &lt;li&gt;Handling update and delete scenarios&lt;/li&gt;

  &lt;li&gt;Expiring dependent objects and collections in cache&lt;/li&gt;

  &lt;li&gt;Handling objects that’s cached with multiple keys&lt;/li&gt;

  &lt;li&gt;Avoid database query optimizations when you cache sets of data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Enjoy. Don’t forget to vote for me!&lt;/p&gt;&lt;div class="wlWriterHeaderFooter" style="margin:0px;padding:0px 0px 0px 0px;"&gt;&lt;a href="http://dotnetburner.com/vote?url=http%3a%2f%2fmsmvps.com%2fblogs%2fomar%2farchive%2f2009%2f11%2f01%2fsimple-way-to-cache-objects-and-collections-for-greater-performance-and-scalability.aspx" rev="vote-for"&gt;&lt;img src="http://dotnetburner.com/image.axd?url=http%3a%2f%2fmsmvps.com%2fblogs%2fomar%2farchive%2f2009%2f11%2f01%2fsimple-way-to-cache-objects-and-collections-for-greater-performance-and-scalability.aspx" style="border:0px;" alt="Burn!" /&gt;&lt;/a&gt;&amp;nbsp;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fmsmvps.com%2fblogs%2fomar%2farchive%2f2009%2f11%2f01%2fsimple-way-to-cache-objects-and-collections-for-greater-performance-and-scalability.aspx" rev="vote-for"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fmsmvps.com%2fblogs%2fomar%2farchive%2f2009%2f11%2f01%2fsimple-way-to-cache-objects-and-collections-for-greater-performance-and-scalability.aspx" style="border:0px;" alt="kick it" /&gt;&lt;/a&gt;&amp;nbsp;&lt;a rev="vote-for" href="http://dotnetshoutout.com/Submit?url=http%3a%2f%2fmsmvps.com%2fblogs%2fomar%2farchive%2f2009%2f11%2f01%2fsimple-way-to-cache-objects-and-collections-for-greater-performance-and-scalability.aspx"&gt;&lt;img alt="Shout it" src="http://dotnetshoutout.com/image.axd?url=http%3a%2f%2fmsmvps.com%2fblogs%2fomar%2farchive%2f2009%2f11%2f01%2fsimple-way-to-cache-objects-and-collections-for-greater-performance-and-scalability.aspx" style="border:0px;" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1736807" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/omar/archive/tags/performance/default.aspx">performance</category><category domain="http://msmvps.com/blogs/omar/archive/tags/linq/default.aspx">linq</category><category domain="http://msmvps.com/blogs/omar/archive/tags/.net/default.aspx">.net</category></item><item><title>Web 2.0 AJAX Portal using jQuery, ASP.NET 3.5, Silverlight, Linq to SQL, WF and Unity</title><link>http://msmvps.com/blogs/omar/archive/2009/04/08/web-2-0-ajax-portal-using-jquery-asp-net-3-5-silverlight-linq-to-sql-wf-and-unity.aspx</link><pubDate>Wed, 08 Apr 2009 18:16:22 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1685991</guid><dc:creator>omar</dc:creator><slash:comments>11</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/omar/rsscomments.aspx?PostID=1685991</wfw:commentRss><comments>http://msmvps.com/blogs/omar/archive/2009/04/08/web-2-0-ajax-portal-using-jquery-asp-net-3-5-silverlight-linq-to-sql-wf-and-unity.aspx#comments</comments><description>&lt;p&gt;&lt;a title="Dropthings Web 2.0 style AJAX portal" href="http://dropthings.omaralzabir.com" target="_blank"&gt;Dropthings&lt;/a&gt; – my &lt;a title="Dropthings - Open Source AJAX Portal" href="http://www.codeplex.com/dropthings" target="_blank"&gt;open source&lt;/a&gt; Web 2.0 Ajax Portal has gone through a technology overhauling. Previously it was built using ASP.NET AJAX, a little bit of Workflow Foundation and Linq to SQL. Now Dropthings boasts full &lt;strong&gt;jQuery&lt;/strong&gt; front-end combined with ASP.NET AJAX &lt;code&gt;UpdatePanel&lt;/code&gt;, &lt;strong&gt;Silverlight widget&lt;/strong&gt;, full &lt;strong&gt;Workflow Foundation&lt;/strong&gt; implementation on the business layer, 100% &lt;strong&gt;Linq to SQL Compiled Queries&lt;/strong&gt; on the data access layer, Dependency Injection and Inversion of Control (IoC) using &lt;strong&gt;Microsoft Enterprise Library 4.1&lt;/strong&gt; and &lt;strong&gt;Unity&lt;/strong&gt;. It also has a ASP.NET AJAX Web Test framework that makes it real easy to write Web Tests that simulates real user actions on AJAX web pages. This article will walk you through the challenges in getting these new technologies to work in an ASP.NET website and how performance, scalability, extensibility and maintainability has significantly improved by the new technologies. Dropthings has been licensed for commercial use by prominent companies including BT Business, Intel, Microsoft IS, Denmark Government portal for Citizens; Startups like Limead and many more. So, this is serious stuff! There’s a very cool open source implementation of Dropthings framework available at &lt;a title="AJAX Portal at National University of Singapore" href="http://nexus.nus.edu.sg/apicta" target="_blank"&gt;National University of Singapore&lt;/a&gt; portal.&lt;/p&gt;  &lt;p&gt;Visit: &lt;a href="http://dropthings.omaralzabir.com"&gt;http://dropthings.omaralzabir.com&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar/image_5F00_57907290.png"&gt;&lt;img title="Dropthings AJAX Portal" style="border-top-width:0px;display:inline;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="529" alt="Dropthings AJAX Portal" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar/image_5F00_thumb_5F00_37551A39.png" width="600" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;I have published a new article on this on CodeProject:&lt;/p&gt;  &lt;p&gt;&lt;a title="Web 2.0 AJAX Portal using jQuery, ASP.NET 3.5, Silverlight, Linq to SQL, WF and Unity" href="http://www.codeproject.com/KB/ajax/Web20Portal.aspx"&gt;http://www.codeproject.com/KB/ajax/Web20Portal.aspx&lt;/a&gt;&lt;/p&gt;  &lt;h2&gt;Get the source code&lt;/h2&gt;  &lt;p&gt;Latest source code is hosted at Google code:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://code.google.com/p/dropthings"&gt;http://code.google.com/p/dropthings&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;There’s a CodePlex site for documentation and issue tracking:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.codeplex.com/dropthings"&gt;http://www.codeplex.com/dropthings&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;You will need Visual Studio 2008 Team Suite with Service Pack 1 and Silverlight 2 SDK in order to run all the projects. If you have only Visual Studio 2008 Professional, then you will have to remove the Dropthings.Test project.&lt;/p&gt;  &lt;h2&gt;New features introduced&lt;/h2&gt;  &lt;p&gt;Dropthings new release has the following features:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Template users – you can define a user who’s pages and widgets are used as a template for new users. Whatever you put in that template user’s pages, it will be copied for every new user. Thus this is an easier way to define the default pages and widgets for new users. Similarly you can do the same for a registered user. The template users can be defined in the &lt;code&gt;web.config&lt;/code&gt;. &lt;/li&gt;    &lt;li&gt;Widget-to-Widget communication – Widgets can send message to each other. Widgets can subscribe to an Event Broker and exchange messages using a Pub-Sub pattern. &lt;/li&gt;    &lt;li&gt;WidgetZone – you can create any number of zones in any shape on the page. You can have widgets laid in horizontal layout, you can have zones on different places on the page and so on. With this zone model, you are no longer limited to the Page-Column model where you could only have N vertical columns. &lt;/li&gt;    &lt;li&gt;Role based widgets – now widgets are mapped to roles so that you can allow different users to see different widget list using &lt;code&gt;ManageWidgetPersmission.aspx.&lt;/code&gt; &lt;/li&gt;    &lt;li&gt;Role based page setup – you can define page setup for different roles. For ex, Managers see different pages and widgets than Employees. &lt;/li&gt;    &lt;li&gt;Widget maximize – you can maximize a widget to take full screen. Handy for widgets with lots of content. &lt;/li&gt;    &lt;li&gt;Free form resize – you can freely resize widgets vertically. &lt;/li&gt;    &lt;li&gt;Silverlight Widgets – You can now make widgets in Silverlight! &lt;/li&gt; &lt;/ul&gt;  &lt;h2&gt;Why the technology overhauling&lt;/h2&gt;  &lt;p&gt;Performance, Scalability, Maintainability and Extensibility – four key reasons for the overhauling. Each new technology solved one of more of these problems. &lt;/p&gt;  &lt;p&gt;First, jQuery was used to replace my personal hand-coded large amount of Javascript code that offered the client side drag &amp;amp; drop and other UI effects. jQuery already has a rich set of library for Drag &amp;amp; Drop, Animations, Event handling, cross browser javascript framework and so on. So, using jQuery means opening the door to thousands of jQuery plugins to be offered on Dropthings. This made Dropthings highly extensible on the client side. Moreover, jQuery is very light. Unlike AJAX Control Toolkit jumbo sized framework and heavy control extenders, jQuery is very lean. So, total javascript size decreased significantly resulting in improved page load time. In total, the jQuery framework, AJAX basic framework, all my stuffs are total 395KB, sweet! Performance is key; it makes or breaks a product.&lt;/p&gt;  &lt;p&gt;Secondly, Linq to SQL queries are replaced with Compiled Queries. Dropthings did not survive a load test when regular lambda expressions were used to query database. I could only reach up to 12 Req/Sec using 20 concurrent users without burning up web server CPU on a Quad Core DELL server. &lt;/p&gt;  &lt;p&gt;Thirdly, Workflow Foundation is used to build operations that require multiple Data Access Classes to perform together in a single transaction. Instead of writing large functions with many if…else conditions, for…loops, it’s better to write them in a Workflow because you can visually see the flow of execution and you can reuse Activities among different Workflows. Best of all, architects can design workflows and developers can fill-in code inside Activities. So, I could design a complex operations in a workflow without writing the real code inside Activities and then ask someone else to implement each Activity. It is like handing over a design document to developers to implement each unit module, only that here everything is strongly typed and verified by compiler. If you strictly follow Single Responsibility Principle for your Activities, which is a smart way of saying one Activity does only one and very simple task, you end up with a highly reusable and maintainable business layer and a very clean code that’s easily extensible.&lt;/p&gt;  &lt;p&gt;Fourthly, &lt;a title="Unity Dependency Injection framework" href="http://www.codeplex.com/unity" target="_blank"&gt;Unity&lt;/a&gt; Dependency Injection (DI) framework is used to pave the path for unit testing and dependency injection. It offers Inversion of Control (IoC), which enables testing individual classes in isolation. Moreover, it has a handy feature to control lifetime of objects. Instead of creating instance of commonly used classes several times within the same request, you can make instances thread level, which means only one instance is created per thread and subsequent calls reuse the same instance. Are these going over your head? No worries, continue reading, I will explain later on.&lt;/p&gt;  &lt;p&gt;Fifthly, enabling API for Silverlight widgets allows more interactive widgets to be built using Silverlight. HTML and Javascripts still have limitations on smooth graphics and continuous transmission of data from web server. Silverlight solves all of these problems.&lt;/p&gt;  &lt;p&gt;Read the article for details on how all these improvements were done and how all these hot techs play together in a very useful open source project for enterprises.&lt;/p&gt;  &lt;p&gt;&lt;a title="Web 2.0 AJAX Portal using jQuery, ASP.NET 3.5, Silverlight, Linq to SQL, WF and Unity" href="http://www.codeproject.com/KB/ajax/Web20Portal.aspx"&gt;http://www.codeproject.com/KB/ajax/Web20Portal.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Don’t forget to vote for me if you like it.&lt;/p&gt;&lt;div class="wlWriterHeaderFooter" style="text-align:left;margin:0px;padding:4px 4px 4px 4px;"&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http://msmvps.com/blogs/omar/archive/2009/04/08/web-2-0-ajax-portal-using-jquery-asp-net-3-5-silverlight-linq-to-sql-wf-and-unity.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://msmvps.com/blogs/omar/archive/2009/04/08/web-2-0-ajax-portal-using-jquery-asp-net-3-5-silverlight-linq-to-sql-wf-and-unity.aspx&amp;amp;bgcolor=0080C0&amp;amp;fgcolor=FFFFFF&amp;amp;border=000000&amp;amp;cbgcolor=808080&amp;amp;cfgcolor=000000" alt="DotNetKicks Image" border="0/" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1685991" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/omar/archive/tags/asp.net/default.aspx">asp.net</category><category domain="http://msmvps.com/blogs/omar/archive/tags/linq/default.aspx">linq</category><category domain="http://msmvps.com/blogs/omar/archive/tags/workflow/default.aspx">workflow</category><category domain="http://msmvps.com/blogs/omar/archive/tags/javascript/default.aspx">javascript</category><category domain="http://msmvps.com/blogs/omar/archive/tags/ajax/default.aspx">ajax</category><category domain="http://msmvps.com/blogs/omar/archive/tags/.net/default.aspx">.net</category><category domain="http://msmvps.com/blogs/omar/archive/tags/silverlight/default.aspx">silverlight</category></item><item><title>Memory Leak with delegates and workflow foundation</title><link>http://msmvps.com/blogs/omar/archive/2009/03/14/memory-leak-with-delegates-and-workflow-foundation.aspx</link><pubDate>Sat, 14 Mar 2009 08:35:53 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1678020</guid><dc:creator>omar</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/omar/rsscomments.aspx?PostID=1678020</wfw:commentRss><comments>http://msmvps.com/blogs/omar/archive/2009/03/14/memory-leak-with-delegates-and-workflow-foundation.aspx#comments</comments><description>&lt;p&gt;Recently after Load Testing my open source project &lt;a href="http://www.dropthings.com" target="_blank"&gt;Dropthings&lt;/a&gt;, I encountered a lot of memory leak. I found lots of Workflow Instances and Linq Entities were left in memory and never collected. After profiling the web application using &lt;a title="Memory Profiler for .NET" href="http://memprofiler.com/" target="_blank"&gt;.NET Memory Profiler&lt;/a&gt;, it showed the real picture:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar/image_5F00_41151CF2.png"&gt;&lt;img title="image" style="border-top-width:0px;display:inline;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="646" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar/image_5F00_thumb_5F00_416D161B.png" width="605" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;It shows you that instances of the several types are being created but not being removed. You see the “New” column has positive value, but the “Remove” column has 0. That means new instances are being created, but not removed. Basically the way you do Memory Profiling is, you take two snapshots. Say you take one snapshot when you first visit your website. Then you do some action on the website that results in allocation of objects. Then you take another snapshot. When you compare both snapshots, you can see how many instances of classes were created between these two snapshots and how many were removed. If they are not equal, then you have leak. Generally in web application many objects are created on every page hit and the end of the request, all those objects are supposed to be released. If they are not released, then we have a problem. But that’s the scenario for desktop applications because in a desktop application, objects can remain in memory until app is closed. But you should know best from the code which objects were supposed to go out of scope and get released.&lt;/p&gt;  &lt;p&gt;For beginners, leak means objects are being allocated but not being freed because someone is holding reference to the objects. When objects leak, they remain in memory forever, until the process (or app domain) is closed. So, if you have a leaky website, your website is continuously taking up memory until it runs out of memory on the web server and thus crash. So, memory leak is a bad – it prevents you from running your product for long duration and requires frequent restart of app pool. &lt;/p&gt;  &lt;p&gt;So, the above screenshot shows Workflow and Linq related classes are not being removed, and thus leaking. This means somewhere workflow instances are not being released and thus all workflow related objects are remaining. You can see the number is same 48 for all workflow related objects. This is a good indication that, almost every instance of workflow is leaked because there were total 48 workflows created and ran. Moreover it indicates we have a leak from a top Workflow instance level, not in some specific Activity or somewhere deep in the code.&lt;/p&gt;  &lt;p&gt;As the workflows use Linq stuff, they held reference to the Linq stuffs and thus the Linq stuffs leaked as well. Sometimes you might be looking for why A is leaking. But you actually end up finding that since B was holding reference to A and B was leaking and thus A was leaking as well. This is sometimes tricky to figure out and you spend a lot of time looking at the wrong direction.&lt;/p&gt;  &lt;p&gt;Now let me show you the buggy code:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;ManualWorkflowSchedulerService manualScheduler &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;br /&gt;&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;  workflowRuntime&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;GetService&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;ManualWorkflowSchedulerService&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;&amp;gt;();

&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;WorkflowInstance instance &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;workflowRuntime&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;CreateWorkflow&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;workflowType&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;, &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;properties&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;);
&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;instance&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Start&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;();

&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#2b91af;"&gt;EventHandler&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;WorkflowCompletedEventArgs&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;&amp;gt; &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;completedHandler &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;null&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;;
&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;completedHandler &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;delegate&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;object &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;o&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;, &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;WorkflowCompletedEventArgs e&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;)
{
    &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;if &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;e&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;WorkflowInstance&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;InstanceId &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;== &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;instance&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;InstanceId&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;) &lt;span style="background:#3f3f3f;color:#7f9f7f;"&gt;// 1. instance&lt;/span&gt;
    {
        &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;workflowRuntime&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;WorkflowCompleted &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;-= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;completedHandler&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;; &lt;span style="background:#3f3f3f;color:#7f9f7f;"&gt;// 2. terminatedhandler&lt;/span&gt;

        &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#7f9f7f;"&gt;// copy the output parameters in the specified properties dictionary
        &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#f0dfaf;"&gt;Dictionary&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;string&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;,&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;object&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;&amp;gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#2b91af;"&gt;Enumerator &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;enumerator &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;br /&gt;&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;            e&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;OutputParameters&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;GetEnumerator&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;();
        &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;while&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;( &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;enumerator&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;MoveNext&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;() )
        {
            &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#2b91af;"&gt;KeyValuePair&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;string&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;,&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;object&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;&amp;gt; &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;pair &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;enumerator&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Current&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;;
            &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;if&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;( &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;properties&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;ContainsKey&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;pair&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Key&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;) )
            {
                &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;properties&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;[&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;pair&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Key&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;] = &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;pair&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Value&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;;
            }
        }
    }
};

&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#f0dfaf;"&gt;Exception &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;x  &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;null&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;;
&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#2b91af;"&gt;EventHandler&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;WorkflowTerminatedEventArgs&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;&amp;gt; &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;terminatedHandler &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;null&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;;
&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;terminatedHandler &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;delegate&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;object &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;o&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;, &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;WorkflowTerminatedEventArgs e&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;)
{
    &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;if &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;e&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;WorkflowInstance&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;InstanceId &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;== &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;instance&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;InstanceId&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;) &lt;span style="background:#3f3f3f;color:#7f9f7f;"&gt;// 3. instance&lt;/span&gt;
    {
        &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;workflowRuntime&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;WorkflowTerminated &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;-= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;terminatedHandler&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;; &lt;span style="background:#3f3f3f;color:#7f9f7f;"&gt;// 4. completeHandler&lt;/span&gt;
        &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Debug&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;WriteLine&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;( &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;e&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Exception &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;);

        &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;x &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;e&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Exception&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;;
    }
};

&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;workflowRuntime&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;WorkflowCompleted &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;+= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;completedHandler&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;;
&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;workflowRuntime&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;WorkflowTerminated &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;+= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;terminatedHandler&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;;

&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;manualScheduler&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;RunWorkflow&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;instance&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;InstanceId&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;);&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Can you spot the code where it leaked?&lt;/p&gt;

&lt;p&gt;I have numbered the lines in comment where the leak is happening. Here the &lt;code&gt;delegate&lt;/code&gt; is acting like a closure and those who are from Javascript background know closure is evil. They leak memory unless very carefully written. Here the &lt;code&gt;delegate&lt;/code&gt; keeps a reference to the &lt;code&gt;instance&lt;/code&gt; object. So, if somehow &lt;code&gt;delegate&lt;/code&gt; is not released, the &lt;code&gt;instance&lt;/code&gt; will remain in memory forever and thus leak. Now can you find a situation when the &lt;code&gt;delegate&lt;/code&gt; will not be released?&lt;/p&gt;

&lt;p&gt;Say the workflow completed. It will fire the &lt;font color="#990000"&gt;completeHandler&lt;code&gt;. &lt;/code&gt;&lt;/font&gt;But the &lt;code&gt;completeHandler&lt;/code&gt; will not release the &lt;code&gt;terminateHandler&lt;code&gt;. &lt;/code&gt;&lt;/code&gt;Thus the &lt;code&gt;terminateHandler&lt;/code&gt; remains in memory and it also holds reference to the &lt;code&gt;instance&lt;/code&gt;. So, we have a leaky &lt;code&gt;delegate&lt;/code&gt; leaking whatever it is holding onto outside it’s scope. Here the only thing outside the scope if the &lt;code&gt;instance&lt;/code&gt;, which it is tried to access from the parent function.&lt;/p&gt;

&lt;p&gt;Since the workflow instance is not released, all the properties the workflow and all the activities inside it are holding onto remains in memory. Most of the workflows and activities expose public properties which are Linq Entities. Thus the Linq Entities remain in memory. Now Linq Entities keep a reference to the &lt;code&gt;DataContext&lt;/code&gt; from where it is produced. Thus we have &lt;code&gt;DataContext&lt;/code&gt; remaining in memory. Moreover, &lt;code&gt;DataContext&lt;/code&gt; keeps reference to many internal objects and metadata cacahe, so they remain in memory as well.&lt;/p&gt;

&lt;p&gt;So, the correct code is:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="background:#3f3f3f;color:#f0dfaf;"&gt;ManualWorkflowSchedulerService &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;manualScheduler &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;br /&gt;    &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;workflowRuntime&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;GetService&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#f0dfaf;"&gt;ManualWorkflowSchedulerService&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;&amp;gt;();

&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#f0dfaf;"&gt;WorkflowInstance &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;instance &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;workflowRuntime&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;CreateWorkflow&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;workflowType&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;, &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;properties&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;);
&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;instance&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Start&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;();
&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;var &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;instanceId &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;instance&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;InstanceId&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;;

&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#2b91af;"&gt;EventHandler&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#f0dfaf;"&gt;WorkflowCompletedEventArgs&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;&amp;gt; &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;completedHandler &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;null&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;;
&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;completedHandler &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;delegate&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;object &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;o&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;, &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#f0dfaf;"&gt;WorkflowCompletedEventArgs &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;e&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;)
{
    &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;if &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;e&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;WorkflowInstance&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;InstanceId &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;== &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;instanceId&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;) &lt;span style="background:#3f3f3f;color:#7f9f7f;"&gt;// 1. instanceId is a Guid&lt;/span&gt;
    {
        &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#7f9f7f;"&gt;// copy the output parameters in the specified properties dictionary
        &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#f0dfaf;"&gt;Dictionary&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;string&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;,&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;object&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;&amp;gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#2b91af;"&gt;Enumerator &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;enumerator &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;br /&gt;                &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;e&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;OutputParameters&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;GetEnumerator&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;();
        &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;while&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;( &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;enumerator&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;MoveNext&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;() )
        {
            &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#2b91af;"&gt;KeyValuePair&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;string&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;,&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;object&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;&amp;gt; &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;pair &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;enumerator&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Current&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;;
            &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;if&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;( &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;properties&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;ContainsKey&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;pair&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Key&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;) )
            {
                &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;properties&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;[&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;pair&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Key&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;] = &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;pair&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Value&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;;
            }
        }
    }
};

&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#f0dfaf;"&gt;Exception &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;x  &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;null&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;;
&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#2b91af;"&gt;EventHandler&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#f0dfaf;"&gt;WorkflowTerminatedEventArgs&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;&amp;gt; &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;terminatedHandler &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;null&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;;
&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;terminatedHandler &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;delegate&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;object &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;o&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;, &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#f0dfaf;"&gt;WorkflowTerminatedEventArgs &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;e&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;)
{
    &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;if &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;e&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;WorkflowInstance&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;InstanceId &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;== &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;instanceId&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;) &lt;span style="background:#3f3f3f;color:#7f9f7f;"&gt;// 2. instanceId is a Guid&lt;/span&gt;
    {
        &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;x &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;e&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Exception&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;;
        &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#f0dfaf;"&gt;Debug&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;WriteLine&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;e&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Exception&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;);
    }
};

&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;workflowRuntime&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;WorkflowCompleted &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;+= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;completedHandler&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;;
&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;workflowRuntime&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;WorkflowTerminated &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;+= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;terminatedHandler&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;;

&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;manualScheduler&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;RunWorkflow&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;instance&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;InstanceId&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;);
&lt;span style="background:#3f3f3f;color:#7f9f7f;"&gt;// 3. Both delegates are now released&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;workflowRuntime&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;WorkflowTerminated &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;-= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;terminatedHandler&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;;
&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;workflowRuntime&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;WorkflowCompleted &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;-= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;completedHandler&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;;&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;There are two changes – in both delegates, the &lt;code&gt;instanceId&lt;/code&gt; variable is passed, instead of the instance. Since &lt;code&gt;instanceId&lt;/code&gt; is a &lt;code&gt;Guid&lt;/code&gt;, which is a struct type data type, not a class, there’s no issue of referencing. Structs are copied, not referenced. So, they don’t leak memory. Secondly, both &lt;code&gt;delegate&lt;/code&gt;s are released at the end of the workflow execution, thus releasing both references.&lt;/p&gt;

&lt;p&gt;In Dropthings, I am using the famous &lt;a title="CallWorkflow Activity" href="http://www.masteringbiztalk.com/blogs/jon/PermaLink,guid,7be9fb53-0ddf-4633-b358-01c3e9999088.aspx" target="_blank"&gt;CallWorkflow Activity by John Flanders&lt;/a&gt;, which is widely used to execute one Workflow from another synchronously. There’s a &lt;code&gt;CallWorkflowService&lt;/code&gt; class which is responsible for synchronously executing another workflow and that has similar memory leak problem. The original code of the service is as following:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;public class &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#f0dfaf;"&gt;CallWorkflowService &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;: &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;WorkflowRuntimeService
&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;{
    &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfaf8f;"&gt;#region &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;Methods

    &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;public void &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;StartWorkflow&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#f0dfaf;"&gt;Type &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;workflowType&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;,&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#f0dfaf;"&gt;Dictionary&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;string&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;,&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;object&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;&amp;gt; &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;inparms&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;, &lt;br /&gt;&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#2b91af;"&gt;           Guid &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;caller&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;,&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#2b91af;"&gt;IComparable &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;qn&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;)
    {
        &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;WorkflowRuntime wr &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;this&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Runtime&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;;
        &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;WorkflowInstance wi &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;wr&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;CreateWorkflow&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;workflowType&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;,&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;inparms&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;);
        &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;wi&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Start&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;();
        &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;ManualWorkflowSchedulerService ss &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;br /&gt;             &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;wr&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;GetService&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;ManualWorkflowSchedulerService&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;&amp;gt;();
        &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;if &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;ss &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;!= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;null&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;)
            &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;ss&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;RunWorkflow&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;wi&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;InstanceId&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;);
        &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#2b91af;"&gt;EventHandler&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;WorkflowCompletedEventArgs&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;&amp;gt; &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;d  &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;null&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;;
        &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;d &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;delegate&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;object &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;o&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;, &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;WorkflowCompletedEventArgs e&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;)
        {
            &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;if &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;e&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;WorkflowInstance&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;InstanceId &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;==&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;wi&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;InstanceId&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;)
            {
                &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;wr&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;WorkflowCompleted &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;-= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;d&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;;
                &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;WorkflowInstance c &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;wr&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;GetWorkflow&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;caller&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;);
                &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;c&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;EnqueueItem&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;qn&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;, &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;e&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;OutputParameters&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;, &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;null&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;, &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;null&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;);
            }
        };
        &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#2b91af;"&gt;EventHandler&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;WorkflowTerminatedEventArgs&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;&amp;gt; &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;te &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;null&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;;
        &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;te &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;delegate&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;object &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;o&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;, &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;WorkflowTerminatedEventArgs e&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;)
        {
            &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;if &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;e&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;WorkflowInstance&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;InstanceId &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;== &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;wi&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;InstanceId&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;)
            {
                &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;wr&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;WorkflowTerminated &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;-= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;te&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;;
                &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;WorkflowInstance c &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;wr&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;GetWorkflow&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;caller&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;);
                &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;c&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;EnqueueItem&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;qn&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;, &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;new &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#f0dfaf;"&gt;Exception&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#c89191;"&gt;&amp;quot;Called Workflow Terminated&amp;quot;&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;, &lt;br /&gt;                  &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;e&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Exception&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;), &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;null&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;, &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;null&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;);
            }
        };
        &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;wr&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;WorkflowCompleted &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;+= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;d&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;;
        &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;wr&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;WorkflowTerminated &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;+= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;te&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;;
    }

    &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfaf8f;"&gt;#endregion &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;Methods
}&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;As you see, it has that same delegate holding reference to instance object problem. Moreover, there’s some queue stuff there, which requires the &lt;code&gt;caller&lt;/code&gt; and &lt;code&gt;qn&lt;/code&gt; parameter passed to the &lt;code&gt;StartWorkflow&lt;/code&gt; function. So, not a straight forward fix. &lt;/p&gt;

&lt;p&gt;I tried to rewrite the whole &lt;code&gt;CallWorkflowService&lt;/code&gt; so that it does not require two delegates to be created per Workflow. Then I took the delegates out. Thus there’s no chance of closure holding reference to unwanted objects. The result looks like this:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;public class &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#f0dfaf;"&gt;CallWorkflowService &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;: &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#f0dfaf;"&gt;WorkflowRuntimeService
&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;{
    &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfaf8f;"&gt;#region &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;Fields

    &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;private &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#2b91af;"&gt;EventHandler&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#f0dfaf;"&gt;WorkflowCompletedEventArgs&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;&amp;gt; &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;_CompletedHandler &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;null&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;;
    &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;private &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#2b91af;"&gt;EventHandler&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#f0dfaf;"&gt;WorkflowTerminatedEventArgs&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;&amp;gt; &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;_TerminatedHandler &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;null&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;;
    &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;private &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#f0dfaf;"&gt;Dictionary&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#2b91af;"&gt;Guid&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;, &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#2b91af;"&gt;WorkflowInfo&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;&amp;gt; &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;_WorkflowQueue &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;br /&gt;&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;       new &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#f0dfaf;"&gt;Dictionary&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#2b91af;"&gt;Guid&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;, &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#2b91af;"&gt;WorkflowInfo&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;&amp;gt;();

    &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfaf8f;"&gt;#endregion &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;Fields

    &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfaf8f;"&gt;#region &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;Methods

    &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;public void &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;StartWorkflow&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#f0dfaf;"&gt;Type &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;workflowType&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;,&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#f0dfaf;"&gt;Dictionary&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;string&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;,&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;object&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;&amp;gt; &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;inparms&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;,&lt;br /&gt;        &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#2b91af;"&gt;Guid &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;caller&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;,&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#2b91af;"&gt;IComparable &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;qn&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;)
    {
        &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#f0dfaf;"&gt;WorkflowRuntime &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;wr &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;this&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Runtime&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;;
        &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#f0dfaf;"&gt;WorkflowInstance &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;wi &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;wr&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;CreateWorkflow&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;workflowType&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;,&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;inparms&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;);
        &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;wi&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Start&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;();

        &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;var &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;instanceId &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;wi&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;InstanceId&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;;
        &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;_WorkflowQueue&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;[&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;instanceId&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;] = &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;new &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#2b91af;"&gt;WorkflowInfo &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;{ &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Caller &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;caller&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;, &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;qn &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;qn &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;};

        &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#f0dfaf;"&gt;ManualWorkflowSchedulerService &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;ss &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;br /&gt;&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;           wr&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;GetService&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#f0dfaf;"&gt;ManualWorkflowSchedulerService&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;&amp;gt;();
        &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;if &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;ss &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;!= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;null&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;)
            &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;ss&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;RunWorkflow&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;wi&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;InstanceId&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;);
    }

    &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;protected override void &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;OnStarted&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;()
    {
        &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;base&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;OnStarted&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;();

        &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;if &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;null &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;== &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;_CompletedHandler&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;)
        {
            &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;_CompletedHandler &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;delegate&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;object &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;o&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;, &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#f0dfaf;"&gt;WorkflowCompletedEventArgs &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;e&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;)
            {
                &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;var &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;instanceId &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;e&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;WorkflowInstance&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;InstanceId&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;;
                &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;if &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;_WorkflowQueue&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;ContainsKey&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;instanceId&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;))
                {
                    &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#2b91af;"&gt;WorkflowInfo &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;wf &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;_WorkflowQueue&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;[&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;instanceId&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;];
                    &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#f0dfaf;"&gt;WorkflowInstance &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;c &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;this&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Runtime&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;GetWorkflow&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;wf&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Caller&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;);
                    &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;c&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;EnqueueItem&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;wf&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;qn&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;, &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;e&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;OutputParameters&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;, &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;null&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;, &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;null&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;);
                    &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;_WorkflowQueue&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Remove&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;instanceId&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;);
                }
            };
            &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;this&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Runtime&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;WorkflowCompleted &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;+= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;_CompletedHandler&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;;
        }

        &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;if &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;null &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;== &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;_TerminatedHandler&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;)
        {
            &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;_TerminatedHandler &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;delegate&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;object &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;o&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;, &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#f0dfaf;"&gt;WorkflowTerminatedEventArgs &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;e&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;)
            {
                &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;var &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;instanceId &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;e&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;WorkflowInstance&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;InstanceId&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;;
                &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;if &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;_WorkflowQueue&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;ContainsKey&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;instanceId&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;))
                {
                    &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#2b91af;"&gt;WorkflowInfo &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;wf &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;_WorkflowQueue&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;[&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;instanceId&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;];
                    &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#f0dfaf;"&gt;WorkflowInstance &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;c &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;this&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Runtime&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;GetWorkflow&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;wf&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Caller&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;);
                    &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;c&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;EnqueueItem&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;wf&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;qn&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;, &lt;br /&gt;&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;                      new &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#f0dfaf;"&gt;Exception&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#c89191;"&gt;&amp;quot;Called Workflow Terminated&amp;quot;&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;, &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;e&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Exception&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;), &lt;br /&gt;&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;                      null&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;, &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;null&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;);
                    &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;_WorkflowQueue&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Remove&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;instanceId&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;);
                }
            };

            &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;this&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Runtime&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;WorkflowTerminated &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;+= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;_TerminatedHandler&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;;
        }
    }

    &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;protected override void &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;OnStopped&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;()
    {
        &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;_WorkflowQueue&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Clear&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;();

        &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;base&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;OnStopped&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;();
    }

    &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfaf8f;"&gt;#endregion &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;Methods

    &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfaf8f;"&gt;#region &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;Nested Types

    &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;private struct &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#2b91af;"&gt;WorkflowInfo
    &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;{
        &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfaf8f;"&gt;#region &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;Fields

        &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;public &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#2b91af;"&gt;Guid &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Caller&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;;
        &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;public &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#2b91af;"&gt;IComparable &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;qn&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;;

        &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfaf8f;"&gt;#endregion &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;Fields
    }

    &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfaf8f;"&gt;#endregion &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;Nested Types
}&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;After fixing the problem, another Memory Profile result showed the leak is gone:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar/image_5F00_0CF441A2.png"&gt;&lt;img title="image" style="border-top-width:0px;display:inline;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="601" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar/image_5F00_thumb_5F00_2BCA8B51.png" width="564" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;As you see, the numbers vary, which means there’s no consistent leak. Moreover, looking at the types that remains in memory, they look more like metadata than instances of classes.&amp;#160; So, they are basically cached instances of metadata, not instances allocated during workflow execution which are supposed to be freed. So, we solved the memory leak!&lt;/p&gt;

&lt;p&gt;Now you know how to write anonymous delegates without leaking memory and how to run workflow without leaking them. Basically, the principle theory is – if you are referencing some outside object from an anonymous &lt;code&gt;delegate&lt;/code&gt;, make sure that object is not holding reference to the &lt;code&gt;delegate&lt;/code&gt; in some way, may be directly or may be via some child objects of its own. Because then you have a circular reference. If possible, do not try to access objects e.g. &lt;code&gt;instance&lt;/code&gt; inside an anonymous delegate that is declared outside the delegate. Try accessing instrinsic data types like int, string, DateTime, Guid etc which are not reference type variables. So, instead of referencing to an object, you should declare local variables e.g. &lt;code&gt;instanceId&lt;/code&gt; that gets the value of properties (e.g. &lt;code&gt;instance.InstanceId&lt;/code&gt;) from the object and then use those local variables inside the anonymous delegate.&lt;/p&gt;&lt;div class="wlWriterHeaderFooter" style="text-align:left;margin:0px;padding:4px 4px 4px 4px;"&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http://msmvps.com/blogs/omar/archive/2009/03/14/memory-leak-with-delegates-and-workflow-foundation.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://msmvps.com/blogs/omar/archive/2009/03/14/memory-leak-with-delegates-and-workflow-foundation.aspx&amp;amp;bgcolor=0080C0&amp;amp;fgcolor=FFFFFF&amp;amp;border=000000&amp;amp;cbgcolor=808080&amp;amp;cfgcolor=000000" alt="DotNetKicks Image" border="0/" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1678020" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/omar/archive/tags/performance/default.aspx">performance</category><category domain="http://msmvps.com/blogs/omar/archive/tags/linq/default.aspx">linq</category><category domain="http://msmvps.com/blogs/omar/archive/tags/workflow/default.aspx">workflow</category><category domain="http://msmvps.com/blogs/omar/archive/tags/.net/default.aspx">.net</category></item><item><title>Linq to SQL solve Transaction deadlock and Query timeout problem using uncommitted reads</title><link>http://msmvps.com/blogs/omar/archive/2009/03/07/linq-to-sql-solve-transaction-deadlock-and-query-timeout-problem-using-uncommitted-reads.aspx</link><pubDate>Sat, 07 Mar 2009 07:30:52 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1676241</guid><dc:creator>omar</dc:creator><slash:comments>11</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/omar/rsscomments.aspx?PostID=1676241</wfw:commentRss><comments>http://msmvps.com/blogs/omar/archive/2009/03/07/linq-to-sql-solve-transaction-deadlock-and-query-timeout-problem-using-uncommitted-reads.aspx#comments</comments><description>&lt;p&gt;When your database tables start accumulating thousands of rows and many users start working on the same table concurrently, SELECT queries on the tables start producing lock contentions and transaction deadlocks. This is a common problem in any high volume website. As soon as you start getting several concurrent users hitting your website that results in SELECT queries on some large table like &lt;u&gt;aspnet_users&lt;/u&gt; table that are also being updated very frequently, you end up having one of these errors:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Transaction (Process ID ##) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction. &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Or,&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Timeout Expired. The Timeout Period Elapsed Prior To Completion Of The Operation Or The Server Is Not Responding. &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The solution to these problems are – use proper index on the table and use transaction isolation level &lt;u&gt;Read Uncommitted&lt;/u&gt; or &lt;u&gt;WITH (NOLOCK)&lt;/u&gt; in your SELECT queries. So, if you had a query like this:&lt;/p&gt;  &lt;pre class="csharpcode"&gt;SELECT * FORM aspnet_users &lt;br /&gt;&lt;span class="kwrd"&gt;where&lt;/span&gt; ApplicationID =’xxx’ AND LoweredUserName = &lt;span class="str"&gt;&amp;#39;someuser&amp;#39;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;You should end up having any of the above errors under high load. There are two ways to solve this:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;SET TRANSACTION LEVEL READ UNCOMMITTED;
SELECT * FROM aspnet_Users &lt;br /&gt;WHERE ApplicationID =’xxx’ AND LoweredUserName = &lt;span class="str"&gt;&amp;#39;someuser&amp;#39;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Or use the WITH (NOLOCK):&lt;/p&gt;

&lt;pre class="csharpcode"&gt;SELECT * FROM aspnet_Users WITH (NOLOCK) &lt;br /&gt;WHERE ApplicationID =’xxx’ AND LoweredUserName = &lt;span class="str"&gt;&amp;#39;someuser&amp;#39;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;The reason for the errors are that since &lt;u&gt;aspnet_users&lt;/u&gt; is a high read and high write table, during read, the table is partially locked and during write, it is also locked. So, when the locks overlap on each other from several queries and especially when there’s a query that’s trying to read a large number of rows and thus locking large number of rows, some of the queries either timeout or produce deadlocks.&lt;/p&gt;

&lt;p&gt;Linq to Sql does not produce queries with the &lt;u&gt;WITH (NOLOCK)&lt;/u&gt; option nor does it use &lt;u&gt;READ UNCOMMITTED&lt;/u&gt;. So, if you are using Linq to SQL queries, you are going to end up with any of these problems on production pretty soon when your site becomes highly popular.&lt;/p&gt;

&lt;p&gt;For example, here’s a very simple query:&lt;/p&gt;

&lt;pre class="code" style="background:#3f3f3f;"&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;using (&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;var &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;db &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;new &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#f0dfaf;"&gt;DropthingsDataContext&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;())
{
    &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;var &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;user &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;db&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;aspnet_Users&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;First&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;();
    &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;var &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;pages &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;user&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Pages&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;ToList&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;();
}&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;&lt;u&gt;DropthingsDataContext&lt;/u&gt; is a &lt;u&gt;DataContext&lt;/u&gt; built from &lt;a title="Dropthings - Open Source AJAX Portal" href="http://www.dropthings.com/" target="_blank"&gt;Dropthings&lt;/a&gt; database.&lt;/p&gt;

&lt;p&gt;When you attach SQL Profiler, you get this:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar/image_5F00_2B685BF8.png"&gt;&lt;img title="image" style="border-top-width:0px;display:inline;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="174" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar/image_5F00_thumb_5F00_7A197197.png" width="639" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;You see none of the queries have READ UNCOMMITTED or WITH (NOLOCK). &lt;/p&gt;

&lt;p&gt;The fix is to do this:&lt;/p&gt;

&lt;pre class="code" style="background:#3f3f3f;"&gt;&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;using (&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;var &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;db &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;new &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#f0dfaf;"&gt;DropthingsDataContext2&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;())
{
    &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;db&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Connection&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Open&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;();
    &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;db&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;ExecuteCommand&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#c89191;"&gt;&amp;quot;SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;&amp;quot;&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;);

    &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;var &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;user &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;db&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;aspnet_Users&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;First&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;();
    &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;var &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;pages &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;user&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Pages&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;ToList&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;();
}&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;This will result in the following profiler output&lt;/p&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar/image_5F00_5DBC09AA.png"&gt;&lt;img title="image" style="border-top-width:0px;display:inline;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="91" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar/image_5F00_thumb_5F00_09202AA5.png" width="630" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;As you see, both queries execute within the same connection and the isolation level is set before the queries execute. So, both queries enjoy the isolation level.&lt;/p&gt;

&lt;p&gt;Now there’s a catch, the connection does not close. This seems to be a bug in the DataContext that when it is disposed, it does not dispose the connection it is holding onto. &lt;/p&gt;

&lt;p&gt;In order to solve this, I have made a child class of the &lt;u&gt;DropthingsDataContext&lt;/u&gt; named &lt;u&gt;DropthingsDataContext2&lt;/u&gt; which overrides the &lt;u&gt;Dispose&lt;/u&gt; method and closes the connection.&lt;/p&gt;

&lt;pre class="code" style="background:#3f3f3f;"&gt;   &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;class &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#f0dfaf;"&gt;DropthingsDataContext2 &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;: &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#f0dfaf;"&gt;DropthingsDataContext&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;, &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#2b91af;"&gt;IDisposable
    &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;{
        &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;public new void &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Dispose&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;()
        {
            &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;if &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;base&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Connection &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;!= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;null&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;)
                &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;if &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;base&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Connection&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;State &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;!= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;System&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Data&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#2b91af;"&gt;ConnectionState&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Closed&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;)
                {
                    &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;base&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Connection&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Close&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;();
                    &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;base&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Connection&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Dispose&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;();
                }

            &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;base&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Dispose&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;();            
        }
    }&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;This solved the connection problem.&lt;/p&gt;

&lt;p&gt;There you have it, no more transaction deadlock or lock contention from Linq to SQL queries. But remember, this is only to eliminate such problems when your database already has the right indexes. If you do not have the proper index, then you will end up having lock contention and query timeouts anyway.&lt;/p&gt;

&lt;p&gt;There’s one more catch, READ UNCOMMITTED will return rows from transactions that have not completed yet. So, you might be reading rows from transactions that will rollback. Since that’s generally an exceptional scenario, you are more or less safe with uncommitted read, but not for financial applications where transaction rollback is a common scenario. In such case, go for committed read or repeatable read.&lt;/p&gt;

&lt;p&gt;There’s another way you can achieve the same, which seems to work, that is using .NET Transactions. Here’s the code snippet:&lt;/p&gt;

&lt;pre class="code" style="background:#3f3f3f;"&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;using &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;var &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;transaction &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;new &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#f0dfaf;"&gt;TransactionScope&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(
    &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#2b91af;"&gt;TransactionScopeOption&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;RequiresNew&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;,
    &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;new &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#2b91af;"&gt;TransactionOptions&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;()
    {
        &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;IsolationLevel &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#2b91af;"&gt;IsolationLevel&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;ReadUncommitted&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;,
        &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Timeout &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#2b91af;"&gt;TimeSpan&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;FromSeconds&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#8acccf;"&gt;30&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;)
    }))
{
    &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;using &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;(&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;var &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;db &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;new &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#f0dfaf;"&gt;DropthingsDataContext&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;())
    {
        &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;var &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;user &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;db&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;aspnet_Users&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;First&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;();
        &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#eaeaac;"&gt;var &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;pages &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;= &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;user&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Pages&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;ToList&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;();

        &lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;transaction&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;.&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dfdfbf;"&gt;Complete&lt;/span&gt;&lt;span style="background:#3f3f3f;color:#dcdccc;"&gt;();
    }
}&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Profiler shows a transaction begins and ends:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar/image_5F00_48683F55.png"&gt;&lt;img title="image" style="border-top-width:0px;display:inline;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="273" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar/image_5F00_thumb_5F00_0F118CC6.png" width="499" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The downside is it wraps your calls in a transaction. So, you are unnecessarily creating transactions even for SELECT operations. When you do this hundred times per second on a web application, it’s a significant over head. &lt;/p&gt;

&lt;p&gt;Some really good examples of deadlocks are given in this article:&lt;/p&gt;

&lt;p&gt;&lt;a title="http://www.code-magazine.com/article.aspx?quickid=0309101&amp;amp;page=2" href="http://www.code-magazine.com/article.aspx?quickid=0309101&amp;amp;page=2"&gt;http://www.code-magazine.com/article.aspx?quickid=0309101&amp;amp;page=2&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I highly recommend it.&lt;/p&gt;
&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fmsmvps.com%2fblogs%2fomar%2farchive%2f2009%2f03%2f07%2flinq-to-sql-solve-transaction-deadlock-and-query-timeout-problem-using-uncommitted-reads.aspx"&gt;&lt;img alt="kick it on DotNetKicks.com" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fmsmvps.com%2fblogs%2fomar%2farchive%2f2009%2f03%2f07%2flinq-to-sql-solve-transaction-deadlock-and-query-timeout-problem-using-uncommitted-reads.aspx" border="0" /&gt;&lt;/a&gt;&lt;div class="wlWriterHeaderFooter" style="text-align:left;margin:0px;padding:4px 4px 4px 4px;"&gt;&lt;script type="text/javascript"&gt;var dzone_url = &amp;#39;http://msmvps.com/blogs/omar/archive/2009/03/07/linq-to-sql-solve-transaction-deadlock-and-query-timeout-problem-using-uncommitted-reads.aspx&amp;#39;;&lt;/script&gt;&lt;script type="text/javascript"&gt;var dzone_title = &amp;#39;Linq to SQL solve Transaction deadlock and Query timeout problem using uncommitted reads&amp;#39;;&lt;/script&gt;&lt;script type="text/javascript"&gt;var dzone_blurb = &amp;#39;Linq to SQL solve Transaction deadlock and Query timeout problem using uncommitted reads&amp;#39;;&lt;/script&gt;&lt;script type="text/javascript"&gt;var dzone_style = &amp;#39;2&amp;#39;;&lt;/script&gt;&lt;script language="javascript" src="http://widgets.dzone.com/widgets/zoneit.js"&gt;&lt;/script&gt; &lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1676241" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/omar/archive/tags/sql+server/default.aspx">sql server</category><category domain="http://msmvps.com/blogs/omar/archive/tags/performance/default.aspx">performance</category><category domain="http://msmvps.com/blogs/omar/archive/tags/linq/default.aspx">linq</category><category domain="http://msmvps.com/blogs/omar/archive/tags/.net/default.aspx">.net</category></item><item><title>Linq to SQL: Delete an entity using Primary Key only</title><link>http://msmvps.com/blogs/omar/archive/2008/10/30/linq-to-sql-delete-an-entity-using-primary-key-only.aspx</link><pubDate>Thu, 30 Oct 2008 00:27:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1652462</guid><dc:creator>omar</dc:creator><slash:comments>18</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/omar/rsscomments.aspx?PostID=1652462</wfw:commentRss><comments>http://msmvps.com/blogs/omar/archive/2008/10/30/linq-to-sql-delete-an-entity-using-primary-key-only.aspx#comments</comments><description>&lt;p&gt;Linq to Sql does not come with a function like &lt;span style="text-decoration:underline;"&gt;.Delete(ID)&lt;/span&gt; which allows you to delete an entity using it&amp;rsquo;s primary key. You have to first get the object that you want to delete and then call &lt;span style="text-decoration:underline;"&gt;.DeleteOnSubmit(obj)&lt;/span&gt; to queue it for delete. Then you have to call &lt;span style="text-decoration:underline;"&gt;DataContext.SubmitChanges()&lt;/span&gt; to play the delete queries on database. So, how to delete object without getting them from database and avoid database roundtrip?&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar/image_5F00_600F7C48.png"&gt;&lt;img title="Delete an object without getting it - Linq to Sql" style="border-top-width:0px;display:inline;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" alt="Delete an object without getting it - Linq to Sql" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar/image_5F00_thumb_5F00_7AABF294.png" border="0" height="168" width="486" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;You can call this function using &lt;span style="text-decoration:underline;"&gt;DeleteByPK&amp;lt;Employee, int&amp;gt;(10, dataContext);&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;First type is the entity type and second one is the type of the primary key. If your object&amp;rsquo;s primary key is a &lt;span style="text-decoration:underline;"&gt;Guid&lt;/span&gt; field, specify &lt;span style="text-decoration:underline;"&gt;Guid&lt;/span&gt; instead of &lt;span style="text-decoration:underline;"&gt;int&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;How it works:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It figures out the table name and the primary key field name from the entity &lt;/li&gt;
&lt;li&gt;Then it uses the table name and primary key field name to build a DELETE query &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Figuring out the table name and primary key field name is a bit hard. There&amp;rsquo;s some reflection involved. The &lt;span style="text-decoration:underline;"&gt;GetTableDef&amp;lt;TSource&amp;gt;()&lt;/span&gt; returns the table name and primary key field name for an entity.&lt;/p&gt;
&lt;p&gt;Every Linq Entity class is decorated with a &lt;span style="text-decoration:underline;"&gt;Table&lt;/span&gt; attribute that has the table name:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar/image_5F00_3E337DEA.png"&gt;&lt;img title="Lint entity declaration" style="border-top-width:0px;display:inline;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" alt="Lint entity declaration" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar/image_5F00_thumb_5F00_3AD1E642.png" border="0" height="67" width="551" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Then the primary key field is decorated with a &lt;span style="text-decoration:underline;"&gt;Column&lt;/span&gt; attribute with &lt;span style="text-decoration:underline;"&gt;IsPrimaryKey = true&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar/image_5F00_7C1CE8DB.png"&gt;&lt;img title="Primary Key field has Column attribute with IsPrimaryKey = true" style="border-top-width:0px;display:inline;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" alt="Primary Key field has Column attribute with IsPrimaryKey = true" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar/image_5F00_thumb_5F00_031BD9BA.png" border="0" height="77" width="709" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;So, using reflection we can figure out the table name and the primary key property and the field name.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s the code that does it:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar/image_5F00_600B6849.png"&gt;&lt;img title="Using reflection find the Table attribute and the Column attribute" style="border-top-width:0px;display:inline;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" alt="Using reflection find the Table attribute and the Column attribute" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar/image_5F00_thumb_5F00_722FCF72.png" border="0" height="615" width="685" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Before you scream &amp;ldquo;Reflection is SLOW!!!!&amp;rdquo; the definition is cached. So, reflection is used only once per appDomain per entity. Subsequent call is just a dictionary lookup away, which is as fast as it can get.&lt;/p&gt;
&lt;p&gt;You can also delete a collection of object without ever getting any one of them. The the following function to delete a whole bunch of objects:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar/image_5F00_57CF1AB4.png"&gt;&lt;img title="Delete a list of objects using Linq to SQL" style="border-top-width:0px;display:inline;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" alt="Delete a list of objects using Linq to SQL" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar/image_5F00_thumb_5F00_3925043E.png" border="0" height="398" width="553" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;The code is available here:&lt;/p&gt;
&lt;p&gt;&lt;a title="http://code.msdn.microsoft.com/DeleteEntitiesLinq" href="http://code.msdn.microsoft.com/DeleteEntitiesLinq"&gt;http://code.msdn.microsoft.com/DeleteEntitiesLinq&lt;/a&gt;&lt;/p&gt;
&lt;div class="wlWriterHeaderFooter" style="text-align:left;margin:0px;padding:4px 4px 4px 4px;"&gt;
&lt;script type="text/javascript"&gt;&lt;/script&gt;
&lt;script type="text/javascript"&gt;&lt;/script&gt;
&lt;script type="text/javascript"&gt;&lt;/script&gt;
&lt;script type="text/javascript"&gt;&lt;/script&gt;
&lt;script language="javascript" src="http://widgets.dzone.com/widgets/zoneit.js"&gt;&lt;/script&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fmsmvps.com%2fblogs%2fomar%2farchive%2f2008%2f10%2f30%2flinq-to-sql-delete-an-entity-using-primary-key-only.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fmsmvps.com%2fblogs%2fomar%2farchive%2f2008%2f10%2f30%2flinq-to-sql-delete-an-entity-using-primary-key-only.aspx" alt="kick it on DotNetKicks.com" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1652462" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/omar/archive/tags/performance/default.aspx">performance</category><category domain="http://msmvps.com/blogs/omar/archive/tags/linq/default.aspx">linq</category><category domain="http://msmvps.com/blogs/omar/archive/tags/.net/default.aspx">.net</category></item><item><title>Solving common problems with Compiled Queries in Linq to Sql for high demand ASP.NET websites</title><link>http://msmvps.com/blogs/omar/archive/2008/10/27/solving-common-problems-with-compiled-queries-in-linq-to-sql-for-high-demand-asp-net-websites.aspx</link><pubDate>Mon, 27 Oct 2008 13:31:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1652150</guid><dc:creator>omar</dc:creator><slash:comments>16</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/omar/rsscomments.aspx?PostID=1652150</wfw:commentRss><comments>http://msmvps.com/blogs/omar/archive/2008/10/27/solving-common-problems-with-compiled-queries-in-linq-to-sql-for-high-demand-asp-net-websites.aspx#comments</comments><description>&lt;p&gt;If you are using Linq to SQL, instead of writing regular Linq Queries, you should be using &lt;a href="http://linqinaction.net/blogs/jwooley/archive/2007/09/04/linq-to-sql-compiled-queries.aspx"&gt;Compiled Queries&lt;/a&gt;. if you are building an ASP.NET web application that&amp;rsquo;s going to get thousands of hits per hour, the execution overhead of Linq queries is going to consume too much CPU and make your site slow. There&amp;rsquo;s a runtime cost associated with each and every Linq Query you write. The queries are parsed and converted to a nice SQL Statement on *every* hit. It&amp;rsquo;s not done at compile time because there&amp;rsquo;s no way to figure out what you might be sending as the parameters in the queries during runtime. So, if you have common Linq to Sql statements like the following one throughout your growing web application, you are soon going to have scalability nightmares:&lt;/p&gt;
&lt;div&gt;
&lt;pre class="csharpcode"&gt;var query = from widget &lt;span class="kwrd"&gt;in&lt;/span&gt; dc.Widgets&lt;br /&gt;                &lt;span class="kwrd"&gt;where&lt;/span&gt; widget.ID == id &amp;amp;&amp;amp; widget.PageID == pageId&lt;br /&gt;                select widget;&lt;br /&gt;&lt;br /&gt;var widget = query.SingleOrDefault();&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;There&amp;rsquo;s &lt;a href="http://www.jdconley.com/blog/archive/2007/11/28/linq-to-sql-surprise-performance-hit.aspx"&gt;a nice blog post by JD Conley&lt;/a&gt; that shows how evil Linq to Sql queries are:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar/image_5F00_03BBB56F.png"&gt;&lt;img title="image" style="border-top-width:0px;display:inline;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar/image_5F00_thumb_5F00_481BA6AE.png" border="0" height="389" width="654" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You see how many times &lt;span style="text-decoration:underline;"&gt;SqlVisitor.Visit&lt;/span&gt; is called to convert a Linq Query to its SQL representation? The runtime cost to convert a Linq query to its SQL Command representation is just way too high.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/ricom/archive/2008/01/14/performance-quiz-13-linq-to-sql-compiled-query-cost-solution.aspx"&gt;Rico Mariani has a very informative performance comparison&lt;/a&gt; of regular Linq queries vs Compiled Linq queries performance:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar/image_5F00_6C608B30.png"&gt;&lt;img title="image" style="border-top-width:0px;display:inline;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar/image_5F00_thumb_5F00_3BEA06BA.png" border="0" height="252" width="531" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Compiled Query wins on every case.&lt;/p&gt;
&lt;p&gt;So, now you know about the benefits of compiled queries. If you are building ASP.NET web application that is going to get high traffic and you have a lot of Linq to Sql queries throughout your project, you have to go for compiled queries. Compiled Queries are built for this specific scenario. &lt;/p&gt;
&lt;p&gt;In this article, I will show you some steps to convert regular Linq to Sql queries to their Compiled representation and how to avoid the dreaded exception &amp;ldquo;&lt;b&gt;Compiled queries across DataContexts with different LoadOptions not supported.&amp;rdquo;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Here are some step by step instruction on converting a Linq to Sql query to its compiled form:&lt;/p&gt;
&lt;p&gt;First we need to find out all the external decision factors in a query. It mostly means parameters in the WHERE clause. Say, we are trying to get a user from &lt;span style="text-decoration:underline;"&gt;aspnet_users&lt;/span&gt; table using Username and Application ID:&lt;/p&gt;
&lt;div&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar/image_5F00_674E27B4.png"&gt;&lt;img title="Query to get a user from aspnet_users table" style="border-top-width:0px;display:inline;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" alt="Query to get a user from aspnet_users table" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar/image_5F00_thumb_5F00_66098ED5.png" border="0" height="57" width="544" /&gt;&lt;/a&gt; &lt;/div&gt;
&lt;p&gt;Here, we have two external decision factor &amp;ndash; one is the Username and another is the Application ID. So, first think this way, if you were to wrap this query in a function that will just return this query as it is, what would you do? You would create a function that takes the &lt;span style="text-decoration:underline;"&gt;DataContext&lt;/span&gt; (dc named here), then two parameters named &lt;span style="text-decoration:underline;"&gt;userName&lt;/span&gt; and &lt;span style="text-decoration:underline;"&gt;applicationID,&lt;/span&gt; right?&lt;/p&gt;
&lt;p&gt;So, be it. We create one function that returns just this query:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar/image_5F00_443DB644.png"&gt;&lt;img title="Converting a LInq Query to a function" style="border-top-width:0px;display:inline;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" alt="Converting a LInq Query to a function" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar/image_5F00_thumb_5F00_4F1A978C.png" border="0" height="103" width="693" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Next step is to replace this function with a &lt;span style="text-decoration:underline;"&gt;Func&amp;lt;&amp;gt;&lt;/span&gt; representation that returns the query. This is the hard part. If you haven&amp;rsquo;t dealt with &lt;span style="text-decoration:underline;"&gt;Func&amp;lt;&amp;gt;&lt;/span&gt; and Lambda expression before, then I suggest you read &lt;a title="Lambda Expression" href="http://blogs.msdn.com/ericwhite/pages/Lambda-Expressions.aspx"&gt;this&lt;/a&gt; and &lt;a title="Lambda Expression" href="http://blah.winsmarts.com/2006/05/19/demystifying-c-30--part-4-lambda-expressions.aspx"&gt;this&lt;/a&gt; and then continue.&lt;/p&gt;
&lt;p&gt;So, here&amp;rsquo;s the delegate representation of the above function:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar/image_5F00_262F8283.png"&gt;&lt;img title="Creating a delegate out of Linq Query" style="border-top-width:0px;display:inline;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" alt="Creating a delegate out of Linq Query" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar/image_5F00_thumb_5F00_4F571AC1.png" border="0" height="114" width="573" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Couple of things to note here. I have declared the delegate as &lt;span style="text-decoration:underline;"&gt;static readonly&lt;/span&gt; because a compiled query is declared only once and reused by all threads. If you don&amp;rsquo;t declare Compiled Queries as static, then you don&amp;rsquo;t get the performance gain because compiling queries everytime when needed is even worse than regular Linq queries. &lt;/p&gt;
&lt;p&gt;Then there&amp;rsquo;s the complex &lt;span style="text-decoration:underline;"&gt;Func&amp;lt;DropthingsDataContext, string, Guid, IQueryable&amp;lt;aspnet_User&amp;gt;&amp;gt;&lt;/span&gt; thing. Basically the generic &lt;span style="text-decoration:underline;"&gt;Func&amp;lt;&amp;gt;&lt;/span&gt; is declared to have three parameters from the &lt;span style="text-decoration:underline;"&gt;GetQuery&lt;/span&gt; function and a return type of &lt;span style="text-decoration:underline;"&gt;IQueryable&amp;lt;aspnet_User&amp;gt;&lt;/span&gt;. Here the parameter types are specified so that the delegate is created strongly typed. &lt;span style="text-decoration:underline;"&gt;Func&amp;lt;&amp;gt;&lt;/span&gt; allows up to 4 parameters and 1 return type. &lt;/p&gt;
&lt;p&gt;Next comes the real business, compiling the query. Now that we have the query in delegate form, we can pass this to &lt;span style="text-decoration:underline;"&gt;CompiledQuery.Compile&lt;/span&gt; function which compiles the delegate and returns a handle to us. Instead of directly assigning the lambda expression to the func, we will pass the expression through the &lt;span style="text-decoration:underline;"&gt;CompiledQuery.Compile&lt;/span&gt; function.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar/image_5F00_0D703573.png"&gt;&lt;img title="Converting a Linq Query to Compiled Query" style="border-top-width:0px;display:inline;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" alt="Converting a Linq Query to Compiled Query" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar/image_5F00_thumb_5F00_093637E1.png" border="0" height="133" width="677" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s where head starts to spin. This is so hard to read and maintain. Bear with me. I just wrapped the lambda expression on the right side inside the &lt;span style="text-decoration:underline;"&gt;CompiledQuery.Compile&lt;/span&gt; function. Basically that&amp;rsquo;s the only change. Also, when you call &lt;span style="text-decoration:underline;"&gt;CompiledQuery.Compile&amp;lt;&amp;gt;&lt;/span&gt;, the generic types must match and be in exactly the same order as the &lt;span style="text-decoration:underline;"&gt;Func&amp;lt;&amp;gt;&lt;/span&gt; declaration.&lt;/p&gt;
&lt;p&gt;Fortunately, calling a compiled query is as simple as calling a function:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar/image_5F00_42D8D1CB.png"&gt;&lt;img title="Running Compiled Query" style="border-top-width:0px;display:inline;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" alt="Running Compiled Query" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar/image_5F00_thumb_5F00_3F773A23.png" border="0" height="89" width="716" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;There you have it, a lot faster Linq Query execution. The hard work of converting all your queries into Compiled Query pays off when you see the performance difference.&lt;/p&gt;
&lt;p&gt;Now, there are some challenges to Compiled Queries. Most common one is, what do you do when you have more than 4 parameters to supply to a Compiled Query? You can&amp;rsquo;t declare a &lt;span style="text-decoration:underline;"&gt;Func&amp;lt;&amp;gt;&lt;/span&gt; with more than 4 types. Solution is to use a &lt;span style="text-decoration:underline;"&gt;struct&lt;/span&gt; to encapsulate all the parameters. Here&amp;rsquo;s an example:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar/image_5F00_2F87F55F.png"&gt;&lt;img title="Using struct in compiled query as parameter" style="border-top-width:0px;display:inline;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" alt="Using struct in compiled query as parameter" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar/image_5F00_thumb_5F00_7CF4721F.png" border="0" height="245" width="736" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Calling the query is quite simple:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar/image_5F00_7660F28F.png"&gt;&lt;img title="Calling compiled query with struct parameter" style="border-top-width:0px;display:inline;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" alt="Calling compiled query with struct parameter" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar/image_5F00_thumb_5F00_575ACEF1.png" border="0" height="55" width="674" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now to the dreaded challenge of using &lt;span style="text-decoration:underline;"&gt;LoadOptions&lt;/span&gt; with Compiled Query. You will notice that the following code results in an exception:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar/image_5F00_039755D6.png"&gt;&lt;img title="Using DataLoadOptions with Compiled Query" style="border-top-width:0px;display:inline;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" alt="Using DataLoadOptions with Compiled Query" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar/image_5F00_thumb_5F00_2D4AAAFC.png" border="0" height="133" width="647" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The above &lt;span style="text-decoration:underline;"&gt;DataLoadOption&lt;/span&gt; runs perfectly when you use regular Linq Queries. But it does not work with compiled queries. When you run this code and the query hits the second time, it produces an exception:&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Compiled queries across DataContexts with different LoadOptions not supported&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;A compiled query remembers the &lt;span style="text-decoration:underline;"&gt;DataLoadOption&lt;/span&gt; once its called. It does not allow executing the same compiled query with a different &lt;span style="text-decoration:underline;"&gt;DataLoadOption&lt;/span&gt; again. Although you are creating the same &lt;span style="text-decoration:underline;"&gt;DataLoadOption&lt;/span&gt; with the same &lt;span style="text-decoration:underline;"&gt;LoadWith&amp;lt;&amp;gt;&lt;/span&gt; calls, it still produces exception because it remembers the exact instance that was used when the compiled query was called for the first time. Since next call creates a new instance of &lt;span style="text-decoration:underline;"&gt;DataLoadOptions&lt;/span&gt;, it does not match and the exception is thrown. You can read details about the problem in &lt;a title="Compiled Queries cannot take same DataLoadOption" href="http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2558764&amp;amp;SiteID=1"&gt;this forum post&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The solution is to use a static &lt;span style="text-decoration:underline;"&gt;DataLoadOption&lt;/span&gt;. You cannot create a local &lt;span style="text-decoration:underline;"&gt;DataLoadOption&lt;/span&gt; instance and use in compiled queries. It needs to be &lt;span style="text-decoration:underline;"&gt;static&lt;/span&gt;. Here&amp;rsquo;s how you can do it:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar/image_5F00_240E6FBB.png"&gt;&lt;img title="image" style="border-top-width:0px;display:inline;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar/image_5F00_thumb_5F00_08F5A0AD.png" border="0" height="146" width="589" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Basically the idea is to construct a &lt;span style="text-decoration:underline;"&gt;static&lt;/span&gt; instance of &lt;span style="text-decoration:underline;"&gt;DataLoadOptions&lt;/span&gt; using a static function. As writing function for every single &lt;span style="text-decoration:underline;"&gt;DataLoadOptions&lt;/span&gt; combination is painful, I created a static delegate here and executed it right on the declaration line. This is in interesting way to declare a variable that requires more than one statement to prepare it. &lt;/p&gt;
&lt;p&gt;Using this option is very simple:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar/image_5F00_4DC1C4E1.png"&gt;&lt;img title="image" style="border-top-width:0px;display:inline;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omar/image_5F00_thumb_5F00_4A602D39.png" border="0" height="73" width="670" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Now you can use &lt;span style="text-decoration:underline;"&gt;DataLoadOptions&lt;/span&gt; with compiled queries. &lt;/p&gt;
&lt;div class="wlWriterHeaderFooter" style="text-align:left;margin:0px;padding:4px 4px 4px 4px;"&gt;
&lt;script type="text/javascript"&gt;&lt;/script&gt;
&lt;script type="text/javascript"&gt;&lt;/script&gt;
&lt;script type="text/javascript"&gt;&lt;/script&gt;
&lt;script type="text/javascript"&gt;&lt;/script&gt;
&lt;script language="javascript" src="http://widgets.dzone.com/widgets/zoneit.js"&gt;&lt;/script&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fmsmvps.com%2fblogs%2fomar%2farchive%2f2008%2f10%2f27%2fsolving-common-problems-with-compiled-queries-in-linq-to-sql-for-high-demand-asp-net-websites.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fmsmvps.com%2fblogs%2fomar%2farchive%2f2008%2f10%2f27%2fsolving-common-problems-with-compiled-queries-in-linq-to-sql-for-high-demand-asp-net-websites.aspx" alt="kick it on DotNetKicks.com" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1652150" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/omar/archive/tags/performance/default.aspx">performance</category><category domain="http://msmvps.com/blogs/omar/archive/tags/linq/default.aspx">linq</category><category domain="http://msmvps.com/blogs/omar/archive/tags/.net/default.aspx">.net</category></item><item><title>My first book - Building a Web 2.0 Portal with ASP.NET 3.5</title><link>http://msmvps.com/blogs/omar/archive/2008/01/13/my-first-book-building-a-web-2-0-portal-with-asp-net-3-5.aspx</link><pubDate>Sun, 13 Jan 2008 20:23:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1461326</guid><dc:creator>omar</dc:creator><slash:comments>44</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/omar/rsscomments.aspx?PostID=1461326</wfw:commentRss><comments>http://msmvps.com/blogs/omar/archive/2008/01/13/my-first-book-building-a-web-2-0-portal-with-asp-net-3-5.aspx#comments</comments><description>&lt;p&gt;My first book &amp;quot;&lt;a href="http://www.oreilly.com/catalog/9780596510503/" target="_blank"&gt;Building a Web 2.0 Portal with ASP.NET 3.5&lt;/a&gt;&amp;quot; from O&amp;#39;Reilly is published and available in the stores. This book explains in detail the architecture design, development, test, deployment, performance and scalability challenges of my open source web portal &lt;a href="http://www.dropthings.com" target="_blank"&gt;Dropthings.com&lt;/a&gt;. Dropthings is a prototype of a web portal similar to &lt;a href="http://www.google.com/ig" target="_blank"&gt;iGoogle&lt;/a&gt; or &lt;a href="http://www.pageflakes.com" target="_blank"&gt;Pageflakes&lt;/a&gt;. But this portal is developed using recently released brand new technologies like ASP.NET 3.5, C# 3.0, Linq to Sql, Linq to XML, and Windows Workflow foundation. It makes heavy use of ASP.NET AJAX 1.0. Throughout my career I have built several state-of-the-art &lt;a href="http://omar.mvps.org" target="_blank"&gt;personal&lt;/a&gt;, educational, enterprise and &lt;a href="http://www.pageflakes.com" target="_blank"&gt;mass consumer web portals&lt;/a&gt;. This book collects my experience in building all of those portals.&lt;/p&gt;&lt;p&gt;O&amp;#39;Reilly Website:&lt;br /&gt;&lt;a href="http://www.oreilly.com/catalog/9780596510503/"&gt;http://www.oreilly.com/catalog/9780596510503/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Amazon:&lt;br /&gt;&lt;a href="http://www.amazon.com/Building-Web-2-0-Portal-ASP-NET/dp/0596510500"&gt;http://www.amazon.com/Building-Web-2-0-Portal-ASP-NET/dp/0596510500&lt;/a&gt;&lt;br /&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Disclaimer: This book does not show you how to build Pageflakes. Dropthings is entirely different in terms of architecture, implementation and the technologies involved.&lt;/p&gt; &lt;p&gt;You learn how to: &lt;/p&gt; &lt;ul&gt; &lt;li&gt;Implement a highly decoupled architecture following the popular n-tier, widget-based application model  &lt;/li&gt;&lt;li&gt;Provide drag-and-drop functionality, and use ASP.NET 3.5 to build the server-side part of the web layer  &lt;/li&gt;&lt;li&gt;Use LINQ to build the data access layer, and Windows Workflow Foundation to build the business layer as a collection of workflows  &lt;/li&gt;&lt;li&gt;Build client-side widgets using JavaScript for faster performance and better caching  &lt;/li&gt;&lt;li&gt;Get maximum performance out of the ASP.NET AJAX Framework for faster, more dynamic, and scalable sites  &lt;/li&gt;&lt;li&gt;Build a custom web service call handler to overcome shortcomings in ASP.NET AJAX 1.0 for asynchronous, transactional, cache-friendly web services  &lt;/li&gt;&lt;li&gt;Overcome JavaScript performance problems, and help the user interface load faster and be more responsive  &lt;/li&gt;&lt;li&gt;Solve various scalability and security problems as your site grows from hundreds to millions of users  &lt;/li&gt;&lt;li&gt;Deploy and run a high-volume production site while solving software, hardware, hosting, and Internet infrastructure problems &lt;/li&gt;&lt;/ul&gt;If you&amp;#39;re ready to build state-of-the art, high-volume web applications that can withstand millions of hits per day, this book has exactly what you need.&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1461326" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/omar/archive/tags/sql+server/default.aspx">sql server</category><category domain="http://msmvps.com/blogs/omar/archive/tags/asp.net/default.aspx">asp.net</category><category domain="http://msmvps.com/blogs/omar/archive/tags/pageflakes/default.aspx">pageflakes</category><category domain="http://msmvps.com/blogs/omar/archive/tags/production/default.aspx">production</category><category domain="http://msmvps.com/blogs/omar/archive/tags/linq/default.aspx">linq</category><category domain="http://msmvps.com/blogs/omar/archive/tags/workflow/default.aspx">workflow</category><category domain="http://msmvps.com/blogs/omar/archive/tags/ajax/default.aspx">ajax</category><category domain="http://msmvps.com/blogs/omar/archive/tags/.net/default.aspx">.net</category><category domain="http://msmvps.com/blogs/omar/archive/tags/IIS/default.aspx">IIS</category></item><item><title>Linq to SQL: How to Attach object to a different data context</title><link>http://msmvps.com/blogs/omar/archive/2007/12/08/linq-to-sql-how-to-attach-object-to-a-different-data-context.aspx</link><pubDate>Sat, 08 Dec 2007 12:59:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1386679</guid><dc:creator>omar</dc:creator><slash:comments>16</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/omar/rsscomments.aspx?PostID=1386679</wfw:commentRss><comments>http://msmvps.com/blogs/omar/archive/2007/12/08/linq-to-sql-how-to-attach-object-to-a-different-data-context.aspx#comments</comments><description>&lt;p&gt;After upgrading to Visual Studio 2008 RTM, you will have trouble
updating Linq to SQL Classes which are read from one data context
and then updated into another data context. You will get this
exception during update:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;
&lt;u&gt;System.NotSupportedException: An attempt has been made to Attach
or Add an entity that is not new, perhaps having been loaded from
another DataContext.&amp;nbsp; This is not supported.
&lt;br /&gt;&lt;/u&gt;
&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Here&amp;#39;s a typical example taken from a 
&lt;a href="http://forums.microsoft.com/msdn/ShowPost.aspx?postid=2524396&amp;amp;siteid=1"&gt;
Forum post&lt;/a&gt;:&lt;/p&gt;
&lt;div&gt;
&lt;div class="csharpcode"&gt;
&lt;pre&gt;
&lt;span class="lnum"&gt;   1:&lt;/span&gt; public static void
UpdateEmployee(Employee employee)
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class="lnum"&gt;   2:&lt;/span&gt; {
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class="lnum"&gt;   3:&lt;/span&gt; using (HRDataContext dataContext =
new HRDataContext())
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class="lnum"&gt;   4:&lt;/span&gt; {
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class="lnum"&gt;   5:&lt;/span&gt; //Get original employee
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class="lnum"&gt;   6:&lt;/span&gt; Employee originalEmployee =
dataContext.Employees.Single(e=
&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;e.EmployeeId==employee.EmployeeId);
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class="lnum"&gt;   7:&lt;/span&gt;  
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class="lnum"&gt;   8:&lt;/span&gt; //attach to datacontext
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class="lnum"&gt;   9:&lt;/span&gt;
dataContext.Employees.Attach(employee, originalEmployee);
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class="lnum"&gt;  10:&lt;/span&gt;  
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class="lnum"&gt;  11:&lt;/span&gt; //save changes
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class="lnum"&gt;  12:&lt;/span&gt; dataContext.SubmitChanges();
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class="lnum"&gt;  13:&lt;/span&gt;  
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class="lnum"&gt;  14:&lt;/span&gt; }
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class="lnum"&gt;  15:&lt;/span&gt; }
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;When you call the Attach function, you will get the exception
mentioned above.&lt;/p&gt;
&lt;p&gt;Here&amp;#39;s a way to do this. First, create a partial class that adds
a 
&lt;u&gt;Detach&lt;/u&gt; method to 
&lt;u&gt;Employee&lt;/u&gt; class. This method will detach the object from it&amp;#39;s
data context and detach associated objects.&lt;/p&gt;
&lt;div&gt;
&lt;div class="csharpcode"&gt;
&lt;pre&gt;
&lt;span class="lnum"&gt;   1:&lt;/span&gt; public partial class Employee
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class="lnum"&gt;   2:&lt;/span&gt; {
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class="lnum"&gt;   3:&lt;/span&gt;   public void Detach()
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class="lnum"&gt;   4:&lt;/span&gt;   {
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class="lnum"&gt;   5:&lt;/span&gt;     this.PropertyChanged = null;
this.PropertyChanging = null;
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class="lnum"&gt;   6:&lt;/span&gt;  
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class="lnum"&gt;   7:&lt;/span&gt;     // Assuming there&amp;#39;s a foreign
key from Employee to Boss
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class="lnum"&gt;   8:&lt;/span&gt;     this.Boss = default(EntityRef
&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;
&lt;span class="html"&gt;Boss&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;);
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class="lnum"&gt;   9:&lt;/span&gt;     // Similarly set child objects
to default as well
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class="lnum"&gt;  10:&lt;/span&gt;  
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class="lnum"&gt;  11:&lt;/span&gt;     this.Subordinates =
default(EntitySet
&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;
&lt;span class="html"&gt;Subordinate&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;);
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class="lnum"&gt;  12:&lt;/span&gt;   }
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class="lnum"&gt;  13:&lt;/span&gt; }
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class="lnum"&gt;  14:&lt;/span&gt;  
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class="lnum"&gt;  15:&lt;/span&gt;  
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Now during update, call 
&lt;u&gt;Detach&lt;/u&gt; before attaching the object to a 
&lt;u&gt;DataContext&lt;/u&gt;.&lt;/p&gt;
&lt;div&gt;
&lt;div class="csharpcode"&gt;
&lt;pre&gt;
&lt;span class="lnum"&gt;   1:&lt;/span&gt; public static void
UpdateEmployee(Employee employee)
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class="lnum"&gt;   2:&lt;/span&gt; {
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class="lnum"&gt;   3:&lt;/span&gt;     using (HRDataContext
dataContext = new HRDataContext())
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class="lnum"&gt;   4:&lt;/span&gt;     {
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class="lnum"&gt;   5:&lt;/span&gt;         //attach to datacontext
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class="lnum"&gt;   6:&lt;/span&gt;         employee.Detach();
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class="lnum"&gt;   7:&lt;/span&gt;  
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class="lnum"&gt;   8:&lt;/span&gt;        
dataContext.Employees.Attach(employee);
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class="lnum"&gt;   9:&lt;/span&gt;         //save changes
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class="lnum"&gt;  10:&lt;/span&gt;  
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class="lnum"&gt;  11:&lt;/span&gt;        
dataContext.SubmitChanges();
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class="lnum"&gt;  12:&lt;/span&gt;     }
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class="lnum"&gt;  13:&lt;/span&gt; }
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class="lnum"&gt;  14:&lt;/span&gt;  
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This&amp;#39;ll work. It assumes the employee object already has its
primary key populated.&lt;/p&gt;
&lt;p&gt;You might see during update, it&amp;#39;s generating a bloated UPDATE
statement where each and every property is appearing on the WHERE
clause. In that case, set 
&lt;u&gt;UpdateCheck&lt;/u&gt; to 
&lt;u&gt;Never&lt;/u&gt; for all properties of 
&lt;u&gt;Employee&lt;/u&gt; class from the Object Relational Designer.&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1386679" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/omar/archive/tags/linq/default.aspx">linq</category><category domain="http://msmvps.com/blogs/omar/archive/tags/.net/default.aspx">.net</category></item><item><title>Data Access usind DLinq</title><link>http://msmvps.com/blogs/omar/archive/2006/12/28/data-access-usind-dlinq.aspx</link><pubDate>Thu, 28 Dec 2006 07:47:36 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:455144</guid><dc:creator>omar</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/omar/rsscomments.aspx?PostID=455144</wfw:commentRss><comments>http://msmvps.com/blogs/omar/archive/2006/12/28/data-access-usind-dlinq.aspx#comments</comments><description>&lt;p&gt;DLinq is so much fun. It&amp;#39;s so amazingly simple to write data access layer that generates really optimized SQL. If you have not used DLinq before, brace for impact! &lt;/p&gt; &lt;p&gt;When you use DLinq, you just design the database and then use &lt;code&gt;SqlMetal.exe&lt;/code&gt; (comes with Linq May CTP) in order to generate a Data Access&amp;nbsp;class&amp;nbsp;which contains all the data access codes and entity classes. Think about the dark age when you had to hand code all entity classes following the database design and hand code data access classes. Whenever your database design changed, you had to modify the entity classes and modify the insert, update, delete, get methods in data access layer. Of course you could use third party ORM tools or use some kind of code generators which generates entity classes from database schema and generates data access layer codes. But do no more, DLinq does it all for you!  &lt;p&gt;The best thing about DLinq is it can generate something called Projection which contains only the necessary fields and not the whole object. There&amp;#39;s no ORM tool or Object Oriented Database library which can do this now because it really needs a custom compiler in order to support this. The benefit of projection is pure performance. You do not SELECT fields which you don&amp;#39;t need, nor do you contruct a jumbo object which has all the fields. DLinq only selects the required fields and creates objects which contains only the selected fields.  &lt;p&gt;Let&amp;#39;s see how easy it is to create a new object in database called &amp;quot;Page&amp;quot;:  &lt;p&gt;&lt;/p&gt; &lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:851a8f6e-2119-435f-a80f-5f51db910fff" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;span style="color:#000000;"&gt;var db &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; DashboardData(ConnectionString);

var newPage &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; Page();
newPage.UserId &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; UserId;
newPage.Title &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; Title;
newPage.CreatedDate &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; DateTime.Now;
newPage.LastUpdate &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; DateTime.Now;

db.Pages.Add(newPage);
db.SubmitChanges();
NewPageId &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; newPage.ID;&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here, DashboardData is the class which SqlMetal.exe generated.&lt;/p&gt;
&lt;p&gt;Say, you want to change a Page&amp;#39;s name:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:3a64b424-2fba-4d60-ad3b-963e207c1a5a" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;span style="color:#000000;"&gt;var page &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; db.Pages.Single( p &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; p.ID &lt;/span&gt;&lt;span style="color:#000000;"&gt;==&lt;/span&gt;&lt;span style="color:#000000;"&gt; PageId );
page.Title &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; PageName;
db.SubmitChanges();&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Here only one row is selected.&lt;/p&gt;
&lt;p&gt;You can also select a single value:&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:99234783-e07d-4c71-9307-515118df9fca" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;span style="color:#000000;"&gt;var UserGuid &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; (from u &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;in&lt;/span&gt;&lt;span style="color:#000000;"&gt; db.AspnetUsers
&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;where&lt;/span&gt;&lt;span style="color:#000000;"&gt; u.LoweredUserName &lt;/span&gt;&lt;span style="color:#000000;"&gt;==&lt;/span&gt;&lt;span style="color:#000000;"&gt; UserName &lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color:#000000;"&gt; u.ApplicationId &lt;/span&gt;&lt;span style="color:#000000;"&gt;==&lt;/span&gt;&lt;span style="color:#000000;"&gt; DatabaseHelper.ApplicationGuid
select u.UserId).Single();&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And here&amp;#39;s the Projection I was talking about:&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:e268993a-a1a5-4527-8e72-2ac64f2d50b9" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;span style="color:#000000;"&gt;var users &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; from u &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;in&lt;/span&gt;&lt;span style="color:#000000;"&gt; db.AspnetUsers
select { UserId &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; u.UserId, UserName &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; u.LoweredUserName };

&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;foreach&lt;/span&gt;&lt;span style="color:#000000;"&gt;( var user &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;in&lt;/span&gt;&lt;span style="color:#000000;"&gt; users )
{
    Debug.WriteLine( user.UserName );
}


&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you want to do some paging like select 20 rows from 100th rows:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:c3ad3da7-0f5f-47a8-a077-c6ed35ecc41b" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;span style="color:#000000;"&gt;var users &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; (from u &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;in&lt;/span&gt;&lt;span style="color:#000000;"&gt; db.AspnetUsers
select { UserId &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; u.UserId, UserName &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; u.LoweredUserName }).Skip(&lt;/span&gt;&lt;span style="color:#000000;"&gt;100&lt;/span&gt;&lt;span style="color:#000000;"&gt;).Take(&lt;/span&gt;&lt;span style="color:#000000;"&gt;20&lt;/span&gt;&lt;span style="color:#000000;"&gt;);

&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;foreach&lt;/span&gt;&lt;span style="color:#000000;"&gt;( var user &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;in&lt;/span&gt;&lt;span style="color:#000000;"&gt; users )
{
    Debug.WriteLine( user.UserName );
}


&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;If you are looking for transaction, see how simple it is:&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:6bc23b8f-818f-43fd-9670-a3c6f5ae66ac" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt;( TransactionScope ts &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; TransactionScope() )
{
    List&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;Page&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; pages &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; db.Pages.Where( p &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; p.UserId &lt;/span&gt;&lt;span style="color:#000000;"&gt;==&lt;/span&gt;&lt;span style="color:#000000;"&gt; oldGuid ).ToList();
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;foreach&lt;/span&gt;&lt;span style="color:#000000;"&gt;( Page page &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;in&lt;/span&gt;&lt;span style="color:#000000;"&gt; pages )
        page.UserId &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; newGuid;
    
    &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt; Change setting ownership&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#000000;"&gt;    UserSetting setting &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; db.UserSettings.Single( u &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; u.UserId &lt;/span&gt;&lt;span style="color:#000000;"&gt;==&lt;/span&gt;&lt;span style="color:#000000;"&gt; oldGuid );
    db.UserSettings.Remove(setting);
    
    setting.UserId &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; newGuid;
    db.UserSettings.Add(setting);
    db.SubmitChanges();

    ts.Complete();
}
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Unbelievable? Believe it.&lt;/p&gt;
&lt;p&gt;You may have some mixed feelings about DLinq performance. Believe me, it generates exactly the right SQL that I wanted it to do. Use SqlProfiler and see the queries it sends to the database. You might also think all these &amp;quot;var&amp;quot; stuffs sounds like late binding in old COM era. It will not be as fast as strongly typed code or your own hand written super optimal code which does exactly what&amp;nbsp;you want. You will be surprised to know that all these DLinq code actually gets transformed into pure and simple .NET 2.0 IL by the Linq compiler. There&amp;#39;s no magic stuff or no additional libraries in order to run these codes in your existing .NET 2.0 project. Unlike many ORM tools, DLinq also does not heavily depend on Reflection.&lt;/p&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=455144" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/omar/archive/tags/linq/default.aspx">linq</category></item><item><title>XLinq: Reading RSS and Atom using XLinq</title><link>http://msmvps.com/blogs/omar/archive/2006/12/26/xlinq-reading-rss-and-atom-using-xlinq.aspx</link><pubDate>Tue, 26 Dec 2006 14:20:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:452931</guid><dc:creator>omar</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/omar/rsscomments.aspx?PostID=452931</wfw:commentRss><comments>http://msmvps.com/blogs/omar/archive/2006/12/26/xlinq-reading-rss-and-atom-using-xlinq.aspx#comments</comments><description>&lt;p&gt;I am playing around with XLinq. I made a RSS Viewer which
downloads RSS/Atom feed and shows a list of links of titles.&lt;/p&gt;
&lt;p&gt;XLinq is so unbelievably easy to use. See in less than 10 lines
I can populate a DataList full of links from RSS/Atom feed. First I
made a DataList:&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:b41d02df-b300-4773-9528-83131c32cbc0" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;

&lt;pre style="background-color:White;"&gt;&lt;/pre&gt;
&lt;div&gt;

&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;
&lt;span style="color:#800000;"&gt;asp:DataList&lt;/span&gt; 
&lt;span style="color:#FF0000;"&gt;ID&lt;/span&gt;
&lt;span style="color:#0000FF;"&gt;=&amp;quot;FeedList&amp;quot;&lt;/span&gt; 
&lt;span style="color:#FF0000;"&gt;runat&lt;/span&gt;
&lt;span style="color:#0000FF;"&gt;=&amp;quot;Server&amp;quot;&lt;/span&gt; 
&lt;span style="color:#FF0000;"&gt;EnableViewState&lt;/span&gt;
&lt;span style="color:#0000FF;"&gt;=&amp;quot;False&amp;quot;&lt;/span&gt;
&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;
&lt;span style="color:#800000;"&gt;ItemTemplate&lt;/span&gt;
&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;
&lt;span style="color:#800000;"&gt;asp:HyperLink&lt;/span&gt; 
&lt;span style="color:#FF0000;"&gt;ID&lt;/span&gt;
&lt;span style="color:#0000FF;"&gt;=&amp;quot;FeedLink&amp;quot;&lt;/span&gt; 
&lt;span style="color:#FF0000;"&gt;runat&lt;/span&gt;
&lt;span style="color:#0000FF;"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt; 
&lt;span style="color:#FF0000;"&gt;Target&lt;/span&gt;
&lt;span style="color:#0000FF;"&gt;=&amp;quot;_blank&amp;quot;&lt;/span&gt; 
&lt;span style="color:#FF0000;"&gt;CssClass&lt;/span&gt;
&lt;span style="color:#0000FF;"&gt;=&amp;quot;feed_item_link&amp;quot;&lt;/span&gt; 
&lt;span style="color:#FF0000;"&gt;NavigateUrl&lt;/span&gt;
&lt;span style="color:#0000FF;"&gt;=&amp;#39;&amp;lt;%#&lt;/span&gt; 
&lt;span style="color:#FF0000;"&gt;Eval(&amp;quot;link&amp;quot;) %&lt;/span&gt;
&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color:#000000;"&gt;&amp;#39;&amp;gt;&lt;/span&gt; 
&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;
&lt;span style="color:#800000;"&gt;%# Eval&lt;/span&gt;
&lt;span style="color:#FF0000;"&gt;(&amp;quot;title&amp;quot;) %&lt;/span&gt;
&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;
&lt;span style="color:#800000;"&gt;asp:HyperLink&lt;/span&gt;
&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;
&lt;span style="color:#800000;"&gt;ItemTemplate&lt;/span&gt;
&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;
&lt;span style="color:#800000;"&gt;asp:DataList&lt;/span&gt;
&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Now use XElement.Load to load a feed from any Url.&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:7280afae-811e-4e6e-a63e-d67eef08b4dd" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;

&lt;pre style="background-color:White;"&gt;&lt;/pre&gt;
&lt;div&gt;

&lt;span style="color:#000000;"&gt;feed&lt;/span&gt; 
&lt;span style="color:#000000;"&gt;=&lt;/span&gt; 
&lt;span style="color:#000000;"&gt;XElement.Load(url);&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;After this, we do a select on the &amp;lt;item&amp;gt; nodes and create
a projection of each node which contains only the title and link
node values. The project acts as a Data Bound Item to the
DataList.&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:e8945e13-fcad-4161-aec9-fcf2d110ff7c" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;

&lt;pre style="background-color:White;"&gt;&lt;/pre&gt;
&lt;div&gt;

&lt;span style="color:#0000FF;"&gt;if&lt;/span&gt;
&lt;span style="color:#000000;"&gt;( feed.Element(&lt;/span&gt;
&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;
&lt;span style="color:#000000;"&gt;channel&lt;/span&gt;
&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt; 
&lt;span style="color:#000000;"&gt;)&lt;/span&gt; 
&lt;span style="color:#000000;"&gt;!=&lt;/span&gt; 
&lt;span style="color:#0000FF;"&gt;null&lt;/span&gt; 
&lt;span style="color:#000000;"&gt;) FeedList.DataSource&lt;/span&gt; 
&lt;span style="color:#000000;"&gt;=&lt;/span&gt; 
&lt;span style="color:#000000;"&gt;(from item&lt;/span&gt; 
&lt;span style="color:#0000FF;"&gt;in&lt;/span&gt; 
&lt;span style="color:#000000;"&gt;feed.Element(&lt;/span&gt;
&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;
&lt;span style="color:#000000;"&gt;channel&lt;/span&gt;
&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;
&lt;span style="color:#000000;"&gt;).Elements(&lt;/span&gt;
&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;
&lt;span style="color:#000000;"&gt;item&lt;/span&gt;
&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;
&lt;span style="color:#000000;"&gt;) select&lt;/span&gt; 
&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt; 
&lt;span style="color:#000000;"&gt;{ title&lt;/span&gt; 
&lt;span style="color:#000000;"&gt;=&lt;/span&gt; 
&lt;span style="color:#000000;"&gt;item.Element(&lt;/span&gt;
&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;
&lt;span style="color:#000000;"&gt;title&lt;/span&gt;
&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;
&lt;span style="color:#000000;"&gt;).Value, link&lt;/span&gt; 
&lt;span style="color:#000000;"&gt;=&lt;/span&gt; 
&lt;span style="color:#000000;"&gt;item.Element(&lt;/span&gt;
&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;
&lt;span style="color:#000000;"&gt;link&lt;/span&gt;
&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;
&lt;span style="color:#000000;"&gt;).Value }).Take(&lt;/span&gt;
&lt;span style="color:#000000;"&gt;3&lt;/span&gt;
&lt;span style="color:#000000;"&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;For Atom, it&amp;#39;s a bit difficult to discover. You need to use Xml
Namespace in order to read through the Atom feed:&lt;/p&gt;
&lt;p&gt;XNamespace ns = &amp;quot;http://www.w3.org/2005/Atom&amp;quot;;&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:43d42837-5ca2-4d94-8b42-fdb3cdce8f5f" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;

&lt;pre style="background-color:White;"&gt;&lt;/pre&gt;
&lt;div&gt;

&lt;span style="color:#0000FF;"&gt;else&lt;/span&gt; 
&lt;span style="color:#0000FF;"&gt;if&lt;/span&gt;
&lt;span style="color:#000000;"&gt;( feed.Element(ns&lt;/span&gt; 
&lt;span style="color:#000000;"&gt;+&lt;/span&gt; 
&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;
&lt;span style="color:#000000;"&gt;entry&lt;/span&gt;
&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;
&lt;span style="color:#000000;"&gt;)&lt;/span&gt; 
&lt;span style="color:#000000;"&gt;!=&lt;/span&gt; 
&lt;span style="color:#0000FF;"&gt;null&lt;/span&gt; 
&lt;span style="color:#000000;"&gt;) FeedList.DataSource&lt;/span&gt; 
&lt;span style="color:#000000;"&gt;=&lt;/span&gt; 
&lt;span style="color:#000000;"&gt;(from item&lt;/span&gt; 
&lt;span style="color:#0000FF;"&gt;in&lt;/span&gt; 
&lt;span style="color:#000000;"&gt;feed.Elements(ns&lt;/span&gt; 
&lt;span style="color:#000000;"&gt;+&lt;/span&gt; 
&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;
&lt;span style="color:#000000;"&gt;entry&lt;/span&gt;
&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;
&lt;span style="color:#000000;"&gt;) select&lt;/span&gt; 
&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt; 
&lt;span style="color:#000000;"&gt;{ title&lt;/span&gt; 
&lt;span style="color:#000000;"&gt;=&lt;/span&gt; 
&lt;span style="color:#000000;"&gt;item.Element(ns&lt;/span&gt; 
&lt;span style="color:#000000;"&gt;+&lt;/span&gt; 
&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;
&lt;span style="color:#000000;"&gt;title&lt;/span&gt;
&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;
&lt;span style="color:#000000;"&gt;).Value, link&lt;/span&gt; 
&lt;span style="color:#000000;"&gt;=&lt;/span&gt; 
&lt;span style="color:#000000;"&gt;item.Element(ns&lt;/span&gt; 
&lt;span style="color:#000000;"&gt;+&lt;/span&gt; 
&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;
&lt;span style="color:#000000;"&gt;link&lt;/span&gt;
&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;
&lt;span style="color:#000000;"&gt;).Attribute(&lt;/span&gt;
&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;
&lt;span style="color:#000000;"&gt;href&lt;/span&gt;
&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;
&lt;span style="color:#000000;"&gt;).Value }).Take(&lt;/span&gt;
&lt;span style="color:#000000;"&gt;3&lt;/span&gt;
&lt;span style="color:#000000;"&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;img height="109" src="http://omar.mvps.org/images/XLinqReadingRSSandAtomusingXLinq_11A50/image0.png" width="243" alt="" /&gt;
&lt;/p&gt;
&lt;p&gt;Cool thing is that you can do paging easily by adding the Take
and Skip methods at the end of Linq expression as I have done here.
Here you see only Take which takes only the specified items from
the feed. If you use Skip, then it will skip elements from
beginning.&lt;/p&gt;
&lt;img src="http://msmvps.com/aggbug.aspx?PostID=452931" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/omar/archive/tags/linq/default.aspx">linq</category></item></channel></rss>