<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Luca Bolognese's WebLog : VB</title><link>http://blogs.msdn.com/lucabol/archive/tags/VB/default.aspx</link><description>Tags: VB</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>My PDC session is online - “Future directions for C# and Visual Basic”</title><link>http://blogs.msdn.com/lucabol/archive/2009/11/23/my-pdc-session-is-online-future-directions-for-c-and-visual-basic.aspx</link><pubDate>Mon, 23 Nov 2009 21:17:44 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9927546</guid><dc:creator>lucabol</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/lucabol/comments/9927546.aspx</comments><wfw:commentRss>http://blogs.msdn.com/lucabol/commentrss.aspx?PostID=9927546</wfw:commentRss><description>&lt;p&gt;In case you are training to play the part of a first generation Italian immigrant in a Broadway show or if you want to understand why I never short msft stock: &lt;a title="http://microsoftpdc.com/Sessions/FT11" href="http://microsoftpdc.com/Sessions/FT11"&gt;http://microsoftpdc.com/Sessions/FT11&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9927546" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/lucabol/archive/tags/C_2300_+Programming/default.aspx">C# Programming</category><category domain="http://blogs.msdn.com/lucabol/archive/tags/.NET+Futures/default.aspx">.NET Futures</category><category domain="http://blogs.msdn.com/lucabol/archive/tags/VB/default.aspx">VB</category></item><item><title>Luca at PDC 2009 next week</title><link>http://blogs.msdn.com/lucabol/archive/2009/11/13/luca-at-pdc-2009-next-week.aspx</link><pubDate>Fri, 13 Nov 2009 18:49:18 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9922139</guid><dc:creator>lucabol</dc:creator><slash:comments>6</slash:comments><comments>http://blogs.msdn.com/lucabol/comments/9922139.aspx</comments><wfw:commentRss>http://blogs.msdn.com/lucabol/commentrss.aspx?PostID=9922139</wfw:commentRss><description>&lt;p&gt;I’ll be in Los Angeles next week for PDC 2009. My session is called “&lt;a href="http://microsoftpdc.com/Sessions/FT11"&gt;Future Directions for C# and Visual Basic&lt;/a&gt;” and it comes on Tuesday immediately after the first keynote.&lt;/p&gt;  &lt;p&gt;I’m planning on spending the first half of the session talking about the biggest trends influencing C# and VB. The second part will be about more future looking features we are playing with these days.&lt;/p&gt;  &lt;p&gt;My deck has just two slides, as always. It’s all about watching me typing code on stage, hoping that I make crazy errors …&lt;/p&gt;  &lt;p&gt;There are several other interesting language related sessions at PDC. Here is a list of them (please notice that the times might change). Also feel free to drop by the languages booth and chat. My team and I will be there most of the time.&lt;/p&gt;  &lt;table border="1" cellspacing="0" cellpadding="0"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="62"&gt;         &lt;p&gt;&lt;b&gt;Day&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="96"&gt;         &lt;p&gt;&lt;b&gt;Time&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="502"&gt;         &lt;p&gt;&lt;b&gt;Title&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="147"&gt;         &lt;p&gt;&lt;b&gt;Presenter&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="117"&gt;         &lt;p&gt;&lt;b&gt;Room&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="62"&gt;         &lt;p&gt;Tues 11/17&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="96"&gt;         &lt;p&gt;11:00 - 12:00&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="502"&gt;         &lt;p&gt;&lt;b&gt;Future Directions for C# and Visual Basic&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="147"&gt;         &lt;p&gt;Luca Bolognese&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="117"&gt;         &lt;p&gt;Hall F&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="62"&gt;         &lt;p&gt;Tues 11/17&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="96"&gt;         &lt;p&gt;11:00 - 12:00&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="502"&gt;         &lt;p&gt;&lt;b&gt;Accelerated Windows Application Development with Microsoft Visual C++ 2010&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="147"&gt;         &lt;p&gt;Boris Jabes&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="117"&gt;         &lt;p&gt;408B&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="62"&gt;         &lt;p&gt;Tues 11/17&lt;b&gt;&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="96"&gt;         &lt;p&gt;12:30 - 13:15&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="502"&gt;         &lt;p&gt;&lt;b&gt;Dynamic Binding in C# 4&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="147"&gt;         &lt;p&gt;Mads Torgersen&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="117"&gt;         &lt;p&gt;Hall F&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="62"&gt;         &lt;p&gt;Tues 11/17&lt;b&gt;&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="96"&gt;         &lt;p&gt;12:30 - 13:15&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="502"&gt;         &lt;p&gt;&lt;b&gt;Using Dynamic Languages to Build Scriptable Applications&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="147"&gt;         &lt;p&gt;Dino Viehland&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="117"&gt;         &lt;p&gt;403AB&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="62"&gt;         &lt;p&gt;Tues 11/17&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="96"&gt;         &lt;p&gt;13:30 - 14:30&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="502"&gt;         &lt;p&gt;&lt;b&gt;C++ Forever: Interactive Applications in the Age of Manycore&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="147"&gt;         &lt;p&gt;Rick Molloy&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="117"&gt;         &lt;p&gt;515B&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="62"&gt;         &lt;p&gt;Tues 11/17&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="96"&gt;         &lt;p&gt;16:30 - 17:30&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="502"&gt;         &lt;p&gt;&lt;b&gt;Manycore and the Microsoft .NET Framework 4: A Match Made in Microsoft Visual Studio 2010&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="147"&gt;         &lt;p&gt;Stephen Toub&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="117"&gt;         &lt;p&gt;502A&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="62"&gt;         &lt;p&gt;Tues 11/17&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="96"&gt;         &lt;p&gt;16:30 - 17:30&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="502"&gt;         &lt;p&gt;&lt;b&gt;Code Contracts and Pex: Power Charge Your Assertions and Unit Tests&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="147"&gt;         &lt;p&gt;Mike Barnett, Nikolai Tillmann&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="117"&gt;         &lt;p&gt;408A&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="62"&gt;         &lt;p&gt;Wed 11/18&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="96"&gt;         &lt;p&gt;11:30 - 12:30&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="502"&gt;         &lt;p&gt;&lt;b&gt;Microsoft Perspectives on the Future of Programming&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="147"&gt;         &lt;p&gt;Panel&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="117"&gt;         &lt;p&gt;Petree Hall C&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="62"&gt;         &lt;p&gt;Wed 11/18&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="96"&gt;         &lt;p&gt;12:00 - 13:00&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="502"&gt;         &lt;p&gt;&lt;b&gt;F# for Architects – Hitting the Sweet Spot&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="147"&gt;         &lt;p&gt;Chris Smith&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="117"&gt;         &lt;p&gt;VS and .NET Pavillion&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="62"&gt;         &lt;p&gt;Wed 11/18&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="96"&gt;         &lt;p&gt;13:00 - 13:45&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="502"&gt;         &lt;p&gt;&lt;b&gt;Code Like the Wind with Microsoft Visual Basic 2010&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="147"&gt;         &lt;p&gt;Lucian Wischik&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="117"&gt;         &lt;p&gt;Petree Hall D&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="62"&gt;         &lt;p&gt;Wed 11/18&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="96"&gt;         &lt;p&gt;13:00 - 13:45&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="502"&gt;         &lt;p&gt;&lt;b&gt;Future of Garbage Collection&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="147"&gt;         &lt;p&gt;Patrick Dussud&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="117"&gt;         &lt;p&gt;Petree Hall C&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="62"&gt;         &lt;p&gt;Wed 11/18&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="96"&gt;         &lt;p&gt;13:00 - 13:45&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="502"&gt;         &lt;p&gt;&lt;b&gt;Microsoft Project Code Name “M”: The Data and Modeling Language&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="147"&gt;         &lt;p&gt;Don Box, Jeff Pinkston&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="117"&gt;         &lt;p&gt;408A&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="62"&gt;         &lt;p&gt;Thu&lt;/p&gt;          &lt;p&gt;11/19&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="96"&gt;         &lt;p&gt;08:30 - 09:30&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="502"&gt;         &lt;p&gt;&lt;b&gt;PLINQ: LINQ, but Faster!&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="147"&gt;         &lt;p&gt;Ed Essey, Igor Ostrovsky&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="117"&gt;         &lt;p&gt;515A&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="62"&gt;         &lt;p&gt;Thu&lt;/p&gt;          &lt;p&gt;11/19&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="96"&gt;         &lt;p&gt;10:00 - 11:00&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="502"&gt;         &lt;p&gt;&lt;b&gt;A Lap around Microsoft Visual Studio 2010 for the Visual Basic Developer &lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="147"&gt;         &lt;p&gt;Lisa Feigenbaum&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="117"&gt;         &lt;p&gt;VS and .NET Pavillion&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="62"&gt;         &lt;p&gt;Thu&lt;/p&gt;          &lt;p&gt;11/19&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="96"&gt;         &lt;p&gt;10:00 - 11:00&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="502"&gt;         &lt;p&gt;&lt;b&gt;Axum: A .NET Language for Safe and Scalable Concurrency&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="147"&gt;         &lt;p&gt;Niklas Gustafsson&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="117"&gt;         &lt;p&gt;515A&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="62"&gt;         &lt;p&gt;Thu&lt;/p&gt;          &lt;p&gt;11/19&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="96"&gt;         &lt;p&gt;11:30 - 12:30&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="502"&gt;         &lt;p&gt;&lt;b&gt;F# for Parallel and Asynchronous Programming&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="147"&gt;         &lt;p&gt;Luke Hoban&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="117"&gt;         &lt;p&gt;515A&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="62"&gt;         &lt;p&gt;Thu&lt;/p&gt;          &lt;p&gt;11/19&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="96"&gt;         &lt;p&gt;12:45 - 13:30&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="502"&gt;         &lt;p&gt;&lt;b&gt;Microsoft Visual C# IDE Tips and Tricks&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="147"&gt;         &lt;p&gt;DJ Park&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="117"&gt;         &lt;p&gt;Petree Hall D&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="62"&gt;         &lt;p&gt;Thu&lt;/p&gt;          &lt;p&gt;11/19&lt;b&gt;&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="96"&gt;         &lt;p&gt;12:45 - 13:30&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="502"&gt;         &lt;p&gt;&lt;b&gt;Microsoft Visual Basic IDE Tips and Tricks&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="147"&gt;         &lt;p&gt;Dustin Campbell&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="117"&gt;         &lt;p&gt;Petree Hall C&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9922139" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/lucabol/archive/tags/C_2300_+Programming/default.aspx">C# Programming</category><category domain="http://blogs.msdn.com/lucabol/archive/tags/.NET+Futures/default.aspx">.NET Futures</category><category domain="http://blogs.msdn.com/lucabol/archive/tags/F_2300_/default.aspx">F#</category><category domain="http://blogs.msdn.com/lucabol/archive/tags/VB/default.aspx">VB</category></item><item><title>A version of the AsyncCache found its way into the Parallel Programming samples …</title><link>http://blogs.msdn.com/lucabol/archive/2009/05/21/a-version-of-the-asynccache-found-its-way-into-the-parallel-programming-samples.aspx</link><pubDate>Thu, 21 May 2009 20:28:13 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9634050</guid><dc:creator>lucabol</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/lucabol/comments/9634050.aspx</comments><wfw:commentRss>http://blogs.msdn.com/lucabol/commentrss.aspx?PostID=9634050</wfw:commentRss><description>&lt;p&gt;Go &lt;a href="http://code.msdn.microsoft.com/ParExtSamples"&gt;here&lt;/a&gt; to download them. It is in \ParallelExtensionsExtras\CoordinationDataStructures. It has a slightly different design in that it returns Tasks. I’m trying to get &lt;a href="http://blogs.msdn.com/pfxteam"&gt;Stephen&lt;/a&gt; to blog about it so that you can compare them.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9634050" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/lucabol/archive/tags/C_2300_+Programming/default.aspx">C# Programming</category><category domain="http://blogs.msdn.com/lucabol/archive/tags/F_2300_/default.aspx">F#</category><category domain="http://blogs.msdn.com/lucabol/archive/tags/VB/default.aspx">VB</category></item><item><title>I talk about C# and VB Co-Evolution on Channel9 (and some F# …)</title><link>http://blogs.msdn.com/lucabol/archive/2009/05/14/i-talk-about-c-and-vb-co-evolution-on-channel9-and-some-f.aspx</link><pubDate>Thu, 14 May 2009 20:26:18 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9616619</guid><dc:creator>lucabol</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/lucabol/comments/9616619.aspx</comments><wfw:commentRss>http://blogs.msdn.com/lucabol/commentrss.aspx?PostID=9616619</wfw:commentRss><description>&lt;p&gt;The title says it all. If you are interested, go &lt;a href="http://channel9.msdn.com/posts/Charles/Luca-Bolognese-C-and-VBNET-Co-Evolution-The-Twain-Shall-Meet/#Page=2"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9616619" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/lucabol/archive/tags/C_2300_+Programming/default.aspx">C# Programming</category><category domain="http://blogs.msdn.com/lucabol/archive/tags/F_2300_/default.aspx">F#</category><category domain="http://blogs.msdn.com/lucabol/archive/tags/VB/default.aspx">VB</category></item><item><title>An Async Html cache – part II – Testing the cache</title><link>http://blogs.msdn.com/lucabol/archive/2009/05/08/an-async-html-cache-part-ii-testing-the-cache.aspx</link><pubDate>Fri, 08 May 2009 18:34:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9589057</guid><dc:creator>lucabol</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/lucabol/comments/9589057.aspx</comments><wfw:commentRss>http://blogs.msdn.com/lucabol/commentrss.aspx?PostID=9589057</wfw:commentRss><description>&lt;P&gt;Other posts:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/lucabol/archive/2009/04/27/an-async-html-cache-part-i.aspx" mce_href="http://blogs.msdn.com/lucabol/archive/2009/04/27/an-async-html-cache-part-i.aspx"&gt;Part I – Writing the cache&lt;/A&gt; &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Let’s try out our little cache. First I want to write a synchronous version of it as a baseline.&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="BACKGROUND: white"&gt;    &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Private Shared Sub &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;TestSync(&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;ByVal &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;sites() &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;As String&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;, &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;ByVal &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;sitesToDownload &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;As Integer&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;, &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;ByVal &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;howLong &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;As Integer&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;)
        &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Dim &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;syncCache &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;As New &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #2b91af"&gt;Dictionary&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;(&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Of String&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;, &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;String&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;)
        &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Dim &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;count = sites.Count()
        &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Dim &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;url1 = &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #a31515"&gt;"http://moneycentral.msn.com/investor/invsub/results/statemnt.aspx?Symbol="

        &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;For &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;i = 0 &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;To &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;sitesToDownload - 1
            &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Dim &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;html &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;As String &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;= &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #a31515"&gt;""
            &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Dim &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;url = url1 &amp;amp; sites(i &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Mod &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;count)
            &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;If Not &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;&lt;STRONG&gt;syncCache.TryGetValue(url, html)&lt;/STRONG&gt; &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Then
                &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;html = LoadWebPage(url)
                &lt;STRONG&gt;syncCache(url) = html&lt;/STRONG&gt;
            &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;End If
            &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;DoWork(html, howLong)
        &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Next
    End Sub&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P&gt;This is a loop that loads webpages in the cache if they are not already there. &lt;EM&gt;sites&lt;/EM&gt; is a list of tickers used to compose the urls; &lt;EM&gt;sitesToDownload&lt;/EM&gt; is the total number of sites to download, so that a single url can be loaded multiple times; &lt;EM&gt;howLong&lt;/EM&gt; represents the work to be done on each loaded page.&lt;/P&gt;
&lt;P&gt;In this version the cache is simply a &lt;EM&gt;Dictionary&lt;/EM&gt; and there is no parallelism. The two bold lines is where the cache is managed.&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;DoWork&lt;/EM&gt; is this.&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="BACKGROUND: white"&gt;    &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Public Shared Sub &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;DoWork(&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;ByVal &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;html &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;As String&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;, &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;ByVal &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;howLong &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;As Integer&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;)
        &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #2b91af"&gt;Thread&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;.Sleep(howLong)
    &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;End Sub&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P&gt;Let’s take a look at the asynchronous version.&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="BACKGROUND: white"&gt;    &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Private Shared Sub &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;TestAsync(&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;ByVal &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;sites() &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;As String&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;, &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;ByVal &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;sitesToDownload &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;As Integer&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;, &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;ByVal &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;howLong &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;As Integer&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;)
        &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Dim &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;htmlCache &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;As New &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #2b91af"&gt;HtmlCache
        &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Dim &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;count = sites.Count()
        &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Dim &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;url = &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #a31515"&gt;"http://moneycentral.msn.com/investor/invsub/results/statemnt.aspx?Symbol="
        &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Using &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;ce = &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;New &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #2b91af"&gt;CountdownEvent&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;(sitesToDownload)
            &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;For &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;i = 1 &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;To &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;sitesToDownload
                &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #2b91af"&gt;htmlCache&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;.GetHtmlAsync(
                    url &amp;amp; sites(i &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Mod &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;count),
                    &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Sub&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;(s)
                        DoWork(s, howLong)
                        ce.Signal()
                    &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;End Sub&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;)
            &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Next
            &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;ce.Wait()
        &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;End Using&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P&gt;There are several points worth making on this:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;The lambda used as second parameter for &lt;EM&gt;GetHtmlAsync&lt;/EM&gt; is invoked on a different thread whenever the html has been retrieved (which could be immediately if the cache has downloaded the url before) &lt;/LI&gt;
&lt;LI&gt;&lt;EM&gt;CountDownEvent&lt;/EM&gt; allows a thread to wait for a certain number of signals to be sent. The waiting happens on the main thread in the &lt;EM&gt;ce.Wait()&lt;/EM&gt; instruction. The triggering of the event happens in the lambda described in the point above (the &lt;EM&gt;ce.Signal() &lt;/EM&gt;instruction) &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;This is the driver for the overall testing.&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="BACKGROUND: white"&gt;    &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Private Shared Sub &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;TestPerf(&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;ByVal &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;s &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;As String&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;, &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;ByVal &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;a &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;As &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #2b91af"&gt;Action&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;, &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;ByVal &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;iterations &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;As Integer&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;)
        &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Dim &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;clock &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;As New &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #2b91af"&gt;Stopwatch

        &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;clock.Start()
        &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;For &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;i = 1 &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;To &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;iterations
            a()
        &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Next
        &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;clock.Stop()
        &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Dim &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;ts = clock.Elapsed
        &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Dim &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;elapsedTime = &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;String&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;.Format(s &amp;amp; &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #a31515"&gt;": {0:00}:{1:00}:{2:00}.{3:00}"&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;, ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10)
        &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;.WriteLine(elapsedTime, &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #a31515"&gt;"RunTime"&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;)
    &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;End Sub&lt;/SPAN&gt;&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;There is not much to say about it. Start the clock, perform a bunch of iterations of the passed lambda, stop the clock, print out performance.&lt;/P&gt;
&lt;P&gt;And finally the main method. Note that all the adjustable parameters are factored out before the calls to &lt;EM&gt;TestPerf&lt;/EM&gt;.&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="BACKGROUND: white"&gt;    &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Public Shared Sub &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;Main()
        &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Dim &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;tickers = &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;New String&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;() {&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #a31515"&gt;"mmm"&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;, &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #a31515"&gt;"aos"&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;, &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #a31515"&gt;"shlm"&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;, &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #a31515"&gt;"cas"&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;, &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #a31515"&gt;"abt"&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;, &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #a31515"&gt;"anf"&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;, &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #a31515"&gt;"abm"&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;, &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #a31515"&gt;"akr"&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;, &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #a31515"&gt;"acet"&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;, &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #a31515"&gt;"afl"&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;, &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #a31515"&gt;"agl"&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;, &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #a31515"&gt;"adc"&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;, &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #a31515"&gt;"apd"&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;,&lt;BR&gt;                                           &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #a31515"&gt;"ayr"&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;, &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #a31515"&gt;"alsk"&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;, &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #a31515"&gt;"ain"&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;, &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #a31515"&gt;"axb"&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;, &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #a31515"&gt;"are"&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;, &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #a31515"&gt;"ale"&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;, &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #a31515"&gt;"ab"&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;, &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #a31515"&gt;"all"&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;}

        &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Dim &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;sitesToDownload = 50
        &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Dim &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;workToDoOnEachUrlInMilliSec = 20
        &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Dim &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;perfIterations = 5

        TestPerf(&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #a31515"&gt;"Async"&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;, &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Sub&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;() TestAsync(tickers, sitesToDownload, workToDoOnEachUrlInMilliSec), perfIterations)
        TestPerf(&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #a31515"&gt;"Sync"&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;, &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Sub&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;() TestSync(tickers, sitesToDownload, workToDoOnEachUrlInMilliSec), perfIterations)
    &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;End Sub&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P&gt;Feel free to change (&lt;EM&gt;tickers&lt;/EM&gt;, &lt;EM&gt;sitesToDownload&lt;/EM&gt;, &lt;EM&gt;workToDoOnEachUrlInMilliSec&lt;/EM&gt;, &lt;EM&gt;perfIterations&lt;/EM&gt;). Depending on the ratios between these parameters and the number of cores on your machine, you’re going to see different results. Which highlights the fact that parallelizing your algorithms can yield performance gains or not depending on both software and hardware considerations. I get ~3X improvement on my box. I attached the full source file for your amusement. &lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9589057" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/lucabol/attachment/9589057.ashx" length="4900" type="text/plain" /><category domain="http://blogs.msdn.com/lucabol/archive/tags/.NET+Futures/default.aspx">.NET Futures</category><category domain="http://blogs.msdn.com/lucabol/archive/tags/VB/default.aspx">VB</category></item><item><title>An Async Html cache – Part I - Writing the cache</title><link>http://blogs.msdn.com/lucabol/archive/2009/04/27/an-async-html-cache-part-i.aspx</link><pubDate>Tue, 28 Apr 2009 02:57:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9572478</guid><dc:creator>lucabol</dc:creator><slash:comments>6</slash:comments><comments>http://blogs.msdn.com/lucabol/comments/9572478.aspx</comments><wfw:commentRss>http://blogs.msdn.com/lucabol/commentrss.aspx?PostID=9572478</wfw:commentRss><description>&lt;P&gt;Other posts:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;&lt;FONT color=#006bad&gt;&lt;A href="http://blogs.msdn.com/lucabol/" mce_href="http://blogs.msdn.com/lucabol/"&gt;Part II - Testing the cache&lt;/A&gt;&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;In the process of converting a financial VBA Excel Addin to .NET (more on that in later posts), I found myself in dire need of a HTML cache that can be called from multiple threads without blocking them. Visualize it as a glorified dictionary where each entry is (url, cachedHtml). The only difference is that when you get the page, you pass a callback to be invoked when the html has been loaded (which could be immediately if the html had already been retrieved by someone else).&lt;/P&gt;
&lt;P&gt;In essence, I want this:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="BACKGROUND: white"&gt;    &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Public Sub &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;GetHtmlAsync(&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;ByVal &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;url &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;As String&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;, &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;ByVal &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;callback &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;As &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #2b91af"&gt;Action&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;(&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Of String&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;))&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P&gt;I’m not a big expert in the &lt;A href="http://msdn.microsoft.com/en-us/concurrency/default.aspx" mce_href="http://msdn.microsoft.com/en-us/concurrency/default.aspx"&gt;.Net Parallel Extensions&lt;/A&gt;, but I’ve got &lt;A href="http://blogs.msdn.com/pfxteam" mce_href="http://blogs.msdn.com/pfxteam"&gt;help&lt;/A&gt;. Stephen Toub helped so much with this that he could have blogged about it himself. And, by the way, this code runs on Visual Studio 2010, which we haven’t shipped yet. I believe with some modifications, it can be run in 2008 + .Net Parallel Extensions CTP, but you’ll have to change a bunch of names.&lt;/P&gt;
&lt;P&gt;In any case, here it comes. First, let’s add some imports.&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="BACKGROUND: white"&gt;Imports &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: black"&gt;System.Collections.Concurrent
&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;Imports &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: black"&gt;System.Threading.Tasks
&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;Imports &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: black"&gt;System.Threading
&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;Imports &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: black"&gt;System.&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #0000a5"&gt;Net&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P&gt;Then, let’s define an asynchronous cache.&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="BACKGROUND: white"&gt;Public Class &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #2b91af"&gt;AsyncCache&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: black"&gt;(&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;Of &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: black"&gt;TKey, &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #0000a5"&gt;TValue&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: black"&gt;)&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P&gt;This thing needs to store the (url, html) pairs somewhere and, luckily enough, there is an handy &lt;EM&gt;ConcurrentDictionary&lt;/EM&gt; that I can use. Also the cache needs to know how to load a &lt;EM&gt;TValue&lt;/EM&gt; given a &lt;EM&gt;TKey&lt;/EM&gt;. In ‘programmingese’, that means.&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="BACKGROUND: white"&gt;    &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Private &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;_loader &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;As &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #2b91af"&gt;Func&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;(&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Of &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #2b91af"&gt;TKey&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;, &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #2b91af"&gt;TValue&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;)
    &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Private &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;_map &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;As New &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #2b91af"&gt;ConcurrentDictionary&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;(&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Of &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #2b91af"&gt;TKey&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;, &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #2b91af"&gt;Task&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;(&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Of &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #2b91af"&gt;TValue&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;))&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P&gt;I’ll need a way to create it.&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="BACKGROUND: white"&gt;    &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Public Sub New&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;(&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;ByVal &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;l &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;As &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #2b91af"&gt;Func&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;(&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Of &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #2b91af"&gt;TKey&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;, &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #2b91af"&gt;TValue&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;))
        _loader = l
    &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;End Sub&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P&gt;Notice in the above code the use of the &lt;EM&gt;Task&lt;/EM&gt; class for my dictionary instead of &lt;EM&gt;TValue&lt;/EM&gt;. Task is a very good abstraction for “do some work asynchronously and call me when you are done”. It’s easy to initialize and it’s easy to attach callbacks to it. Indeed, this is what we’ll do next:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="BACKGROUND: white"&gt;    &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Public Sub &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;GetValueAsync(&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;ByVal &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;key &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;As &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #2b91af"&gt;TKey&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;, &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;ByVal &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;callback &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;As &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #2b91af"&gt;Action&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;(&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Of &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #2b91af"&gt;TValue&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;))

        &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Dim &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;task &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;As &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #2b91af"&gt;Task&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;(&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Of &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #2b91af"&gt;TValue&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;) = &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Nothing
        If Not &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;_map.TryGetValue(key, task) &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Then
            &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;task = &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;New &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #2b91af"&gt;Task&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;(&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Of &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #2b91af"&gt;TValue&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;)(&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Function&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;() _loader(key), &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #2b91af"&gt;TaskCreationOptions&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;.DetachedFromParent)
            &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;If &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;_map.TryAdd(key, task) &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Then
                &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #2b91af"&gt;task&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;.Start()
            &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Else
                &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #2b91af"&gt;task&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;.Cancel()
                _map.TryGetValue(key, task)
            &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;End If
        End If

        &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #2b91af"&gt;task&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;.ContinueWith(&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Sub&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;(t) callback(t.Result))
    &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;End Sub&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P&gt;Wow. Ok, let me explain. This method is divided in two parts. The first part is just a thread safe way to say “give me the task corresponding to this key or, if the task hasn’t been inserted in the cache yet, create it and insert it”. The second part just says “add callback to the list of functions to be called when the task has finished running”.&lt;/P&gt;
&lt;P&gt;The first part needs some more explanation. What is &lt;SPAN style="BACKGROUND: white; COLOR: #2b91af"&gt;TaskCreationOptions&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;.DetachedFromParent? It essentially says that the created task is not going to prevent the parent task from terminating. In essence, the task that created the child task won’t wait for its conclusion. The rest is better explained in comments.&lt;/SPAN&gt;&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="BACKGROUND: white"&gt;        &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;If Not &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;_map.TryGetValue(key, task) &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Then &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: green"&gt;' Is the task in the cache? (Loc. X)
            &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;task = &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;New &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #2b91af"&gt;Task&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;(&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Of &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #2b91af"&gt;TValue&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;)(&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Function&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;() _loader(key), &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #2b91af"&gt;TaskCreationOptions&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;.DetachedFromParent) &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: green"&gt;' No, create it
            &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;If &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;_map.TryAdd(key, task) &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Then &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: green"&gt;' Try to add it
                &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #2b91af"&gt;task&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;.Start() &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: green"&gt;' I succeeded. I’m the one who added this task. I can safely start it.
            &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;Else
                &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #2b91af"&gt;task&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;.Cancel() &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: green"&gt;' I failed, someone inserted the task after I checked in (Loc. X). Cancel it.
                &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;_map.TryGetValue(key, task) &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: green"&gt;' And get the one that someone inserted
            &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: blue"&gt;End If
        End If&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P&gt;Got it? Well, I admit I trust Stephen that this is what I should do …&lt;/P&gt;
&lt;P&gt;I can then create my little HTML Cache by using the above class as in:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="BACKGROUND: white"&gt;Public Class &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #2b91af"&gt;HtmlCache
&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;
    Public Sub &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: black"&gt;GetHtmlAsync(&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;ByVal &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: black"&gt;url &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;As String&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: black"&gt;, &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;ByVal &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: black"&gt;callback &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;As &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #2b91af"&gt;Action&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: black"&gt;(&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;Of String&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: black"&gt;))
        _asyncCache.GetValueAsync(url, callback)
    &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;End Sub

    Private Function &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: black"&gt;LoadWebPage(&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;ByVal &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: black"&gt;url &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;As String&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: black"&gt;) &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;As String
        Using &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: black"&gt;client &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;As New &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #2b91af"&gt;WebClient&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: black"&gt;()
            &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: green"&gt;'Test.PrintThread("Downloading on thread {0} ...")
            &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;Return &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: black"&gt;client.DownloadString(url)
        &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;End Using
    End Function

    Private &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: black"&gt;_asyncCache &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;As New &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: #2b91af"&gt;AsyncCache&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: black"&gt;(&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;Of String&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: black"&gt;, &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;String&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: black"&gt;)(&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;AddressOf &lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white; COLOR: black"&gt;LoadWebPage)

&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND: white"&gt;End Class&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P&gt;I have no idea why coloring got disabled when I copy/paste. It doesn’t matter, this is trivial. I just create an &lt;EM&gt;AsyncCache&lt;/EM&gt; and initialize it with a method that knows how to load a web page. I then simply implement &lt;EM&gt;GetHtmlAsync&lt;/EM&gt; by delegating to the underlying &lt;EM&gt;GetValueAsync&lt;/EM&gt; on &lt;EM&gt;AsyncCache&lt;/EM&gt;.&lt;/P&gt;
&lt;P&gt;It is somehow bizarre to call &lt;EM&gt;Webclient.DownloadString&lt;/EM&gt;, when the design could be revised to take advantage of its asynchronous version. Maybe I’ll do it in another post. Next time, I’ll write code to use this thing.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9572478" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/lucabol/archive/tags/.NET+Futures/default.aspx">.NET Futures</category><category domain="http://blogs.msdn.com/lucabol/archive/tags/VB/default.aspx">VB</category></item></channel></rss>