<?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>Rob Windsor's Weblog : DevCenter</title><link>http://msmvps.com/blogs/windsor/archive/tags/DevCenter/default.aspx</link><description>Tags: DevCenter</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP2 (Build: 40407.4157)</generator><item><title>TechEd Developer 2008</title><link>http://msmvps.com/blogs/windsor/archive/2008/05/17/teched-developer-2008.aspx</link><pubDate>Sat, 17 May 2008 11:47:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1623804</guid><dc:creator>windsor</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/windsor/rsscomments.aspx?PostID=1623804</wfw:commentRss><comments>http://msmvps.com/blogs/windsor/archive/2008/05/17/teched-developer-2008.aspx#comments</comments><description>&lt;p&gt;The spring conference season keeps on chugging along. The MVP Summit and DevTeach just finished and TechEd is just around the corner. &lt;/p&gt;
&lt;p&gt;It will be interesting to see&amp;nbsp;what effect&amp;nbsp;splitting the conference into a developer week and an IT Pro week will have. I&amp;#39;ve been spending a lot of time with SharePoint lately and that&amp;#39;s a topic that has firm roots on both sides. I&amp;#39;m sure there are many other disciplines&amp;nbsp;(SQL Server and VSTS&amp;nbsp;come to mind) that are in the same boat.&lt;/p&gt;
&lt;p&gt;This year I&amp;#39;ll be taking it easier on the &amp;quot;networking&amp;quot; than I have in the past. I&amp;#39;m moderating a Birds-of-a-Feather (BoF) session and&amp;nbsp;co-presenting an early-morning&amp;nbsp;TLC talk and want to do so with a clear head. I&amp;#39;ll also still be in the process of upgrading &lt;a href="http://www.objectsharp.com/training/coursedetail.aspx?id=1122"&gt;ObjectSharp&amp;#39;s ASP.NET course&lt;/a&gt; from 2.0 to 3.5 which will be delivered for the first time the week following the conference.&lt;/p&gt;
&lt;p&gt;I went through the session builder earlier and there are a ton of things I want to see. I had two or three (sometimes even more) sessions per time slot that I wanted to see. This morning I deleted all those and later this weekend I&amp;#39;m going to go through and pick the sessions that I absolutely don&amp;#39;t want to miss (my sessions for example) and put those in Outlook. Everything else will be done spur of the moment at the conference.&lt;/p&gt;
&lt;p&gt;For those of you who are attending&amp;nbsp;the conference for the first time, you might want to check out my &lt;a href="http://msmvps.com/blogs/windsor/archive/2006/06/18/a-guide-to-attending-teched-or-pdc.aspx"&gt;Guide to Attending TechEd or PDC&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I&amp;#39;ll be Twittering (&lt;a title="http://twitter.com/rob_windsor" href="http://twitter.com/rob_windsor"&gt;http://twitter.com/rob_windsor&lt;/a&gt;) and&amp;nbsp;hopefully blogging from the conference. If you&amp;#39;re there feel free to look me up or better yet drop by one of my sessions.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;WIN07-TLC Strategies for Moving Microsoft Visual Basic 6 Applications to Microsoft .NET&lt;/b&gt;&lt;br /&gt;Wednesday, June 4 8:30 AM - 9:45 AM&lt;br /&gt;Blue Theatre 1&lt;/p&gt;
&lt;p&gt;&lt;b&gt;BOF806 Strategies for Moving Your Microsoft Visual Basic 6 Investments to .NET&lt;br /&gt;&lt;/b&gt;Thursday, June 5 1:00 PM - 2:15 PM&lt;br /&gt;S330 E&lt;/p&gt;
&lt;p&gt;Technorati Tags: [&lt;a href="http://technorati.com/tag/TechEd" rel="tag"&gt;TechEd&lt;/a&gt;, &lt;a href="http://technorati.com/tag/Visual+Basic" rel="tag"&gt;Visual Basic&lt;/a&gt;, &lt;a href="http://technorati.com/tag/VB" rel="tag"&gt;VB&lt;/a&gt;]&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1623804" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/windsor/archive/tags/Development/default.aspx">Development</category><category domain="http://msmvps.com/blogs/windsor/archive/tags/DevCenter/default.aspx">DevCenter</category><category domain="http://msmvps.com/blogs/windsor/archive/tags/VB/default.aspx">VB</category><category domain="http://msmvps.com/blogs/windsor/archive/tags/TechEd/default.aspx">TechEd</category></item><item><title>Talking WCF on Devcasting</title><link>http://msmvps.com/blogs/windsor/archive/2008/04/12/talking-wcf-on-devcasting.aspx</link><pubDate>Sat, 12 Apr 2008 14:26:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1584335</guid><dc:creator>windsor</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/windsor/rsscomments.aspx?PostID=1584335</wfw:commentRss><comments>http://msmvps.com/blogs/windsor/archive/2008/04/12/talking-wcf-on-devcasting.aspx#comments</comments><description>&lt;p&gt;While I was in Vegas for &lt;a href="http://msmvps.com/blogs/windsor/archive/2008/03/27/un-mix-2008.aspx"&gt;Un-Mix 08&lt;/a&gt;, I sat down with &lt;a href="http://derekh.com/"&gt;Derek Hatchard&lt;/a&gt; to record a show for &lt;a href="http://devcasting.com/"&gt;Devcasting&lt;/a&gt;. About a week later Derek decided to repave his machine but unfortunately, he forgot to backup the recording of the interview. We got together over Skype to re-record a couple weeks ago. What started out as an interview on WCF turned into a 90 minute conversation on all things geek.&lt;/p&gt;
&lt;p&gt;Derek&amp;#39;s done some editing and has extracted the WCF interview part into a show which you can check out at the link below. Stay tuned for part two where we talk about Mix, WPF, and more.&lt;/p&gt;
&lt;p&gt;&lt;a title="http://devcasting.com/index.php/2008/04/10/devcasting-10-wcf-with-rob-windsor/" href="http://devcasting.com/index.php/2008/04/10/devcasting-10-wcf-with-rob-windsor/"&gt;http://devcasting.com/index.php/2008/04/10/devcasting-10-wcf-with-rob-windsor/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Happy listening.&lt;/p&gt;
&lt;p&gt;
&lt;script src="http://feeds.feedburner.com/~s/rwindsor?i=http://msmvps.com/blogs/windsor/archive/2008/04/12/talking-wcf-on-devcasting.aspx" type="text/javascript"&gt;&lt;/script&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1584335" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/windsor/archive/tags/Development/default.aspx">Development</category><category domain="http://msmvps.com/blogs/windsor/archive/tags/WCF/default.aspx">WCF</category><category domain="http://msmvps.com/blogs/windsor/archive/tags/DevCenter/default.aspx">DevCenter</category><category domain="http://msmvps.com/blogs/windsor/archive/tags/VB/default.aspx">VB</category><category domain="http://msmvps.com/blogs/windsor/archive/tags/Podcast/default.aspx">Podcast</category></item><item><title>TechEd BOF Session: Strategies for Moving Your Microsoft Visual Basic 6 Investments to .NET</title><link>http://msmvps.com/blogs/windsor/archive/2008/03/29/teched-bof-session-strategies-for-moving-your-microsoft-visual-basic-6-investments-to-net.aspx</link><pubDate>Sat, 29 Mar 2008 03:02:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1560015</guid><dc:creator>windsor</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/windsor/rsscomments.aspx?PostID=1560015</wfw:commentRss><comments>http://msmvps.com/blogs/windsor/archive/2008/03/29/teched-bof-session-strategies-for-moving-your-microsoft-visual-basic-6-investments-to-net.aspx#comments</comments><description>&lt;p&gt;If you&amp;#39;re not familiar with the concept, a Birds-of-a-Feather (BOF) session is an open discussion lead by a moderator who is not a Microsoft employee. The sessions are not presentations, there are no projectors. Unlike the Keynotes and Breakout sessions which are mostly one to many communication, Birds-of-a-Feather sessions are many to many communication and don&amp;#39;t necessarily focus on Microsoft products or technology.&amp;nbsp; They are about people talking with people - connecting, sharing, networking, and creating community. &lt;/p&gt;
&lt;p&gt;This year I&amp;#39;d like to do a BOF session at TechEd Developer&lt;strong&gt;. &lt;/strong&gt;From my expereince with the community at user groups and conferences it&amp;#39;s pretty clear that there are lots of developers who still work with classic VB code at least part of the time. Many are still questioning what to do with this legacy code and how to move it forward or integrate it with .NET. So I&amp;#39;ve proposed the following:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;i&gt;&lt;strong&gt;Strategies for Moving Your Microsoft Visual Basic 6 Investments to .NET&lt;/strong&gt;: For years Visual Basic 6 (VB 6) was used by organizations world-wide to build key line-of-business applications and components. Now they have thousands to millions of lines of code representing a significant organizational investment. Many have struggled in the past trying to move this legacy code base to .NET, many are just starting that journey. The path from VB 6 to .NET has not always been clear - there are options but there is no one size fits all approach. One option is to rewrite your applications so you can re-architect and take advantage of all the features .NET has to offer. Another is to migrate the applications so automated tools like the Code Advisor and the Migration Wizard can assist you. Finally, you can use COM Interop and the Interop Forms Toolkit to continue leveraging existing working assets while phasing in new features built on the .NET Framework. In this session we will discuss all three options and explore the pros and cons of each. The goal is raise awareness of the choices and the tools available so you will be able to pick the best strategy for your organization going forward.&lt;/i&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;strike&gt;So, if you&amp;#39;re going to TechEd and you&amp;#39;d like to join in on the discussion, please head on over to the &lt;/strike&gt;&lt;a href="https://www.msteched.com/dev/voting.aspx"&gt;&lt;strike&gt;BOF voting page&lt;/strike&gt;&lt;/a&gt;&lt;strike&gt; and add your vote. Voting closes on April 7.&lt;/strike&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strike&gt;&lt;strong&gt;Update:&lt;/strong&gt;&lt;br /&gt;The BOF was selected. It&amp;#39;s running on Wednesday, June 4 from 8:30 to 9:45 AM. I think to room is S330 EF but I&amp;#39;m not positive. If you&amp;#39;re planning on attending please let me know&amp;nbsp;the subject(s) you&amp;#39;d like to discuss by adding a comment.&lt;/strike&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update (April 28, 2008):&lt;br /&gt;&lt;/strong&gt;The BOF was selected. It&amp;#39;s BOF806 and is running Thursday, June 5 from 1:00 to 2:15 pm. If you&amp;#39;re planning on attending please let me know the subject(s) you&amp;#39;d like to discuss by adding a comment.&lt;/p&gt;
&lt;p&gt;See you then.&lt;/p&gt;
&lt;p&gt;
&lt;script src="http://feeds.feedburner.com/~s/rwindsor?i=http://msmvps.com/blogs/windsor/archive/2008/03/29/teched-bof-session-strategies-for-moving-your-microsoft-visual-basic-6-investments-to-net.aspx" type="text/javascript"&gt;&lt;/script&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1560015" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/windsor/archive/tags/Development/default.aspx">Development</category><category domain="http://msmvps.com/blogs/windsor/archive/tags/DevCenter/default.aspx">DevCenter</category><category domain="http://msmvps.com/blogs/windsor/archive/tags/VB/default.aspx">VB</category><category domain="http://msmvps.com/blogs/windsor/archive/tags/TechEd/default.aspx">TechEd</category></item><item><title>Visual Studio 2008 to be Released on November 15th?</title><link>http://msmvps.com/blogs/windsor/archive/2007/11/11/visual-studio-2008-to-be-released-on-november-15th.aspx</link><pubDate>Sun, 11 Nov 2007 16:37:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1299352</guid><dc:creator>windsor</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/windsor/rsscomments.aspx?PostID=1299352</wfw:commentRss><comments>http://msmvps.com/blogs/windsor/archive/2007/11/11/visual-studio-2008-to-be-released-on-november-15th.aspx#comments</comments><description>&lt;p&gt;Don Box hints that it may be so.&lt;/p&gt;
&lt;p&gt;&lt;a title="http://www.pluralsight.com/blogs/dbox/archive/2007/11/10/49001.aspx" href="http://www.pluralsight.com/blogs/dbox/archive/2007/11/10/49001.aspx"&gt;http://www.pluralsight.com/blogs/dbox/archive/2007/11/10/49001.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;
&lt;script src="http://feeds.feedburner.com/~s/rwindsor?i=http://msmvps.com/blogs/windsor/archive/2007/11/11/visual-studio-2008-to-be-released-on-november-15th.aspx.aspx" type="text/javascript"&gt;&lt;/script&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1299352" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/windsor/archive/tags/Development/default.aspx">Development</category><category domain="http://msmvps.com/blogs/windsor/archive/tags/DevCenter/default.aspx">DevCenter</category><category domain="http://msmvps.com/blogs/windsor/archive/tags/VB/default.aspx">VB</category></item><item><title>Visual Studio 2008 "How Do I" Videos</title><link>http://msmvps.com/blogs/windsor/archive/2007/10/16/visual-studio-2008-quot-how-do-i-quot-videos.aspx</link><pubDate>Tue, 16 Oct 2007 01:56:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1247963</guid><dc:creator>windsor</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/windsor/rsscomments.aspx?PostID=1247963</wfw:commentRss><comments>http://msmvps.com/blogs/windsor/archive/2007/10/16/visual-studio-2008-quot-how-do-i-quot-videos.aspx#comments</comments><description>&lt;p&gt;If you&amp;#39;re interested in seeing some of the new features of Visual Studio 2008 in action, you should check out the series of &amp;quot;How Do I&amp;quot; videos at &lt;a title="http://www.visualstudio2008beta.com/videos.htm" href="http://www.visualstudio2008beta.com/videos.htm"&gt;http://www.visualstudio2008beta.com/videos.htm&lt;/a&gt;. There are 13 up there now and&amp;nbsp;more will be added every week. If you want to play along, head on over to&amp;nbsp;&lt;a title="http://msdn2.microsoft.com/en-us/vstudio/aa700831.aspx" href="http://msdn2.microsoft.com/en-us/vstudio/aa700831.aspx"&gt;http://msdn2.microsoft.com/en-us/vstudio/aa700831.aspx&lt;/a&gt;&amp;nbsp;and download a copy of Beta 2 for yourself. &amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
&lt;script src="http://feeds.feedburner.com/~s/rwindsor?i=http://msmvps.com/blogs/windsor/archive/2007/10/16/visual-studio-2008-quot-how-do-i-quot-videos.aspx" type="text/javascript"&gt;&lt;/script&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1247963" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/windsor/archive/tags/Development/default.aspx">Development</category><category domain="http://msmvps.com/blogs/windsor/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/windsor/archive/tags/Training/default.aspx">Training</category><category domain="http://msmvps.com/blogs/windsor/archive/tags/DevCenter/default.aspx">DevCenter</category><category domain="http://msmvps.com/blogs/windsor/archive/tags/VB/default.aspx">VB</category><category domain="http://msmvps.com/blogs/windsor/archive/tags/Videos/default.aspx">Videos</category></item><item><title>Using a Splash Screen from an External Assembly in Visual Basic 2005</title><link>http://msmvps.com/blogs/windsor/archive/2007/08/18/using-a-splash-screen-from-an-external-assembly-in-visual-basic-2005.aspx</link><pubDate>Sat, 18 Aug 2007 21:08:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1122257</guid><dc:creator>windsor</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/windsor/rsscomments.aspx?PostID=1122257</wfw:commentRss><comments>http://msmvps.com/blogs/windsor/archive/2007/08/18/using-a-splash-screen-from-an-external-assembly-in-visual-basic-2005.aspx#comments</comments><description>&lt;p&gt;This issue came up on one of email lists I&amp;#39;m involved in and I though the solution was worth sharing. The&amp;nbsp;developer wanted to know how to&amp;nbsp;use a splash screen from an external assembly (i.e. a DLL)&amp;nbsp;in a&amp;nbsp;Visual Basic&amp;nbsp;2005 Windows application. If you look at&amp;nbsp;the Applications tab of the project properties, there is&amp;nbsp;dropdown to pick the splash screen but it will only show forms in the current project. &lt;/p&gt;
&lt;p&gt;&lt;a title="Photo Sharing" href="http://www.flickr.com/photos/rwindsor/1163425512/"&gt;&lt;img height="316" alt="Application Framework Screenshot" src="http://farm2.static.flickr.com/1414/1163425512_19e7a8d3f5_o.jpg" width="506" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;To use a splash screen from an external assembly click the View Application Events button to get the partial class for the application and then override the OnCreateSplashScreen method. The code should look something like this.&lt;/p&gt;
&lt;div style="BACKGROUND:#eeeeee;COLOR:black;FONT-FAMILY:consolas, lucida console, courier new;"&gt;
&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;19&lt;/span&gt;&amp;nbsp;&lt;span style="COLOR:blue;"&gt;Partial&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;Friend&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;Class&lt;/span&gt; MyApplication&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;20&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;span style="COLOR:blue;"&gt;Global&lt;/span&gt;.System.Diagnostics.DebuggerStepThroughAttribute()&amp;gt; _&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;21&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;Protected&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;Overrides&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;Sub&lt;/span&gt; OnCreateSplashScreen()&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;22&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;Me&lt;/span&gt;.SplashScreen = &lt;span style="COLOR:blue;"&gt;New&lt;/span&gt; ClassLibrary1.SplashScreen1()&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;23&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;End&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;Sub&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:#2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;24&lt;/span&gt;&amp;nbsp;&lt;span style="COLOR:blue;"&gt;End&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;Class&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
&lt;script src="http://feeds.feedburner.com/~s/rwindsor?i=http://msmvps.com/blogs/windsor/archive/2007/08/18/using-a-splash-screen-from-an-external-assembly-in-visual-basic-2005.aspx" type="text/javascript"&gt;&lt;/script&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1122257" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/windsor/archive/tags/Development/default.aspx">Development</category><category domain="http://msmvps.com/blogs/windsor/archive/tags/DevCenter/default.aspx">DevCenter</category><category domain="http://msmvps.com/blogs/windsor/archive/tags/VB/default.aspx">VB</category></item><item><title>Application Settings Made Easy with My and Visual Basic 2005</title><link>http://msmvps.com/blogs/windsor/archive/2007/01/28/application-settings-made-easy-with-my-and-visual-basic-2005.aspx</link><pubDate>Sun, 28 Jan 2007 08:56:20 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:524841</guid><dc:creator>windsor</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/windsor/rsscomments.aspx?PostID=524841</wfw:commentRss><comments>http://msmvps.com/blogs/windsor/archive/2007/01/28/application-settings-made-easy-with-my-and-visual-basic-2005.aspx#comments</comments><description>&lt;p&gt;&lt;/p&gt; &lt;p&gt;Most applications require some configuration settings that could change over time. Classic examples would be a connection string to a database, the URL to your company web site, or the path to a log file. These settings could be stored in the application itself but this would mean that, should the setting change, the application would have to be modified, recompiled, and redeployed. A better approach would be to store the values of these settings in some external data store; traditionally this has been an INI file, a “plain” XML file, or the Windows registry.  &lt;p&gt;When .NET was introduced it included built in support for configuration files which, amongst other things, could store application settings. To store settings you have to add specific XML tags and values into the configuration file so that associated classes in the Framework will be able to access them. For example, if you wanted to add a setting called AppBackColor you would include the following in your configuration file:  &lt;p&gt;&lt;font face="Lucida Console"&gt;&amp;lt;configuration&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;appSettings&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add key=”AppBackColor” value=”AntiqueWhite” /&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;/appSettings&amp;gt;&lt;br /&gt;&amp;lt;/configuration&amp;gt;&lt;/font&gt;  &lt;p&gt;You would then be able to access the setting using:  &lt;p&gt;&lt;font face="Lucida Console"&gt;Imports System.Configuration&lt;br /&gt;Private Sub Form1_Load(...) Handles MyBase.Load&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim backColor As String&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; backColor = ConfigurationSettings.AppSettings(&amp;quot;AppBackColor&amp;quot;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Me.BackColor = Color.FromName(backColor)&lt;br /&gt;End Sub&lt;/font&gt;  &lt;p&gt;There are three main issues with this procedure. First, you need to know the format of XML that’s needed in the configuration file. Second, you access the individual settings by passing their name as a string to the AppSettings object. And third, the setting value comes back to you as a string.  &lt;p&gt;This means you have three potential points of failure that will all rear their ugly heads at runtime. You could potentially put improperly formatted XML in the configuration file, you could type the name of the setting incorrectly when trying to access it, and you could give the setting an invalid value (in the example above that would be something that is not a know color to .NET).  &lt;p&gt;In Visual Basic 2005 you have another option. Microsoft has added both Visual Studio designers and new .NET Framework classes to make management and use of settings much, much easier. To add a new setting or to change an existing one, open your project properties, select the Settings tab, and you will be presented with the settings editor grid (see Figure 1).  &lt;p&gt;&lt;a title="Flickr Photos" href="http://www.flickr.com/photos/15413839@N00/371646537/"&gt;&lt;img alt="Settings Grid with an application setting" src="http://farm1.static.flickr.com/133/371646553_3f152181d4_o.jpg" border="0" /&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Figure 1 – Settings Grid with an application setting&lt;/strong&gt; &lt;/p&gt; &lt;p&gt;Each setting now has four properties instead of just the two used previously. The Name and Value are there as before but now you also have a Type and a Scope. The Type property allows us to strongly type the setting, meaning that you cannot set an initial Value that is not of the correct type and when you use the setting in code you will not have to cast or convert it from a string. The final property is Scope which can be set to Application or User. Application scoped settings are read-only and serve the same function as settings in previous versions of Visual Basic while user scoped settings are specific to an individual user and can be modified in code. User scoped settings will be discussed later in this article.  &lt;p&gt;The data you’ve entered in the settings grid is saved in the configuration file as before, it’s just done for us by the designer. You don’t have to know which tags are required and what their attributes are nor do you have to worry about spelling or capitalization mistakes. Entering the settings shown in Figure 1 will result in this being added to the configuration file:  &lt;p&gt;&lt;font face="Lucida Console"&gt;&amp;lt;configuration&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;!-- other stuff not related to settings --&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;applicationSettings&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;SettingsDemo.My.MySettings&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;setting name=&amp;quot;AppBackColor&amp;quot; serializeAs=&amp;quot;String&amp;quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;value&amp;gt;AntiqueWhite&amp;lt;/value&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/setting&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/SettingsDemo.My.MySettings&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;/applicationSettings&amp;gt;&lt;br /&gt;&amp;lt;/configuration&amp;gt;&lt;/font&gt;  &lt;p&gt;Now that the new setting has been configured, it can be used in your code. In this case you could use it to initialize the background color of the main form. The setting is accessed using the My namespace (which is a major addition to Visual Basic 2005) and is much cleaner than our previous example.  &lt;p&gt;&lt;font face="Lucida Console"&gt;Private Sub Form1_Load(...) Handles MyBase.Load&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Me.BackColor = My.Settings.AppBackColor&lt;br /&gt;End Sub&lt;/font&gt;  &lt;p&gt;It’s important to note that AppBackColor has become a property of the Settings class. When your application starts, Visual Basic reads the settings from the configuration file and builds these properties dynamically. Because your setting is now a property you don’t have to worry about typing the name incorrectly (you’ll get a compiler error if you do) and you get the benefits of strong typing. That is the value of the AppBackColor property is a Color, not a string that needs to be converted to a Color.  &lt;p&gt;You can see that these new features address the issues found in the older settings architecture and greatly ease the process of managing and using application settings. But wait, there’s more! There’s still user scoped settings to cover.  &lt;p&gt;Designer and .NET Framework support for user scoped settings, or per-user settings, is wholly new to Visual Basic 2005 (For information on how to accomplish this in previous versions of Visual Basic.NET, see Rocky Lhotka’s article entitled Storing User Configurations which can be found at &lt;a href="http://shrinkster.com/c3x)"&gt;http://shrinkster.com/c3x)&lt;/a&gt;. User settings are used in much the same way as application settings but the effect is quite different.  &lt;p&gt;You add a user setting in exactly the same way as an application setting but you set the Scope to User. Figure 2 shows a user setting called UserFont with an initial value of Microsoft Sans Serif, 8.25pt.  &lt;p&gt;&lt;a title="Flickr Photos" href="http://www.flickr.com/photos/15413839@N00/371646537/"&gt;&lt;img alt="Settings Grid with an application and a user setting" src="http://farm1.static.flickr.com/166/371646537_a54d042e35_o.jpg" border="0" /&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Figure 2 – Settings Grid with an application and a user setting&lt;/strong&gt; &lt;/p&gt; &lt;p&gt;This new setting will update the configuration file to look like this:  &lt;p&gt;&lt;font face="Lucida Console"&gt;&amp;lt;configuration&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;!-- other stuff not related to settings --&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;userSettings&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;SettingsDemo.My.MySettings&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;setting name=&amp;quot;UserFont&amp;quot; serializeAs=&amp;quot;String&amp;quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;value&amp;gt;Microsoft Sans Serif, 8.25pt&amp;lt;/value&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/setting&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/SettingsDemo.My.MySettings&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;/userSettings&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;applicationSettings&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;SettingsDemo.My.MySettings&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;setting name=&amp;quot;AppBackColor&amp;quot; serializeAs=&amp;quot;String&amp;quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;value&amp;gt;AntiqueWhite&amp;lt;/value&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/setting&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/SettingsDemo.My.MySettings&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;/applicationSettings&amp;gt;&lt;br /&gt;&amp;lt;/configuration&amp;gt;&lt;/font&gt;  &lt;p&gt;And, as before, the new setting can now be used in code.  &lt;p&gt;&lt;font face="Lucida Console"&gt;Private Sub Form1_Load(...) Handles MyBase.Load&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Me.BackColor = My.Settings.AppBackColor&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Me.Font = My.Settings.UserFont&lt;br /&gt;End Sub&lt;/font&gt;  &lt;p&gt;This, however, is where the similarities end. As mentioned previously, user settings are specific to a user and can be modified at runtime. So what happens when you change a setting for a user? Let’s assume you have a menu option that lets the user change the font for the main form of our application. If the user does change the font, you’ll likely want to save their choice so that you can restore it the next time the application runs. To do this you will use the UserFont setting.  &lt;p&gt;When the application closes you will set UserFont to the font of the main form and then save the setting.  &lt;p&gt;&lt;font face="Lucida Console"&gt;Private Sub Form1_FormClosed(...) Handles Me.FormClosed&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; My.Settings.UserFont = Me.Font&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; My.Settings.Save()&lt;br /&gt;End Sub&lt;/font&gt;  &lt;p&gt;When you do this a user specific configuration file called user.config will be created in a folder under the Documents and Settings for the person currently logged in to Windows. This file will store the setting data specific to that user.  &lt;p&gt;Nice? It gets even better. You can actually achieve the same result without any code. The Windows Forms designer supports binding user settings to properties of forms or controls. For example, you could bind the UserFont setting to the Font property of our application’s main form (Form1). In the Properties Window for Form1 find (ApplicationSettings) and expand it. Then select (PropertyBinding) and click the button with the ellipses to open the binding editor form (see Figure 3). Finally, select the Font property, click the dropdown, and select UserFont from the list.  &lt;p&gt;&lt;a title="Flickr Photos" href="http://www.flickr.com/photos/15413839@N00/371646574/"&gt;&lt;img alt="Binding a user setting to a property" src="http://farm1.static.flickr.com/155/371646574_ebe38bd0bc_o.jpg" border="0" /&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Figure 3 – Binding a user setting to a property&lt;/strong&gt; &lt;/p&gt; &lt;p&gt;With this done you no longer need to set the Font property in the Form’s Load event and you don’t need to set UserFont in the FornClosed event either. The data binding handles this for us.  &lt;p&gt;The last thing to mention is the call to My.Settings.Save which you saw in the FormClosed event. This actually wasn’t necessary, it was added it for completeness. If you look in the Application tab of your Project Properties you’ll see a CheckBox with the caption “Save My.Settings on Shutdown” (see Figure 4). If this is checked (and it is by default) then Visual Basic will automatically save user settings just before the application terminates. The combination of this option and the visual tools to bind settings to form and control properties give you a no-code solution for implementing user settings. &lt;/p&gt; &lt;p&gt;&lt;a title="Flickr Photos" href="http://www.flickr.com/photos/15413839@N00/371646537/"&gt;&lt;img alt="Enabling the automatic saving if user settings" src="http://farm1.static.flickr.com/186/371646557_f2c844a316_o.jpg" border="0" /&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Figure 4 – Enabling the automatic saving if user settings.&lt;/strong&gt; &lt;/p&gt; &lt;p&gt;As you’ve seen, the addition of My to Visual Basic 2005, new classes to the .NET Framework 2.0 and new designers to Visual Studio 2005 vastly improves our ability to manage and use application and user specific settings in our applications.&lt;/p&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=524841" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/windsor/archive/tags/Development/default.aspx">Development</category><category domain="http://msmvps.com/blogs/windsor/archive/tags/Article/default.aspx">Article</category><category domain="http://msmvps.com/blogs/windsor/archive/tags/DevCenter/default.aspx">DevCenter</category><category domain="http://msmvps.com/blogs/windsor/archive/tags/VB/default.aspx">VB</category></item><item><title>Some Specifics on Generics</title><link>http://msmvps.com/blogs/windsor/archive/2007/01/03/some-specifics-on-generics.aspx</link><pubDate>Wed, 03 Jan 2007 09:07:56 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:466635</guid><dc:creator>windsor</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/windsor/rsscomments.aspx?PostID=466635</wfw:commentRss><comments>http://msmvps.com/blogs/windsor/archive/2007/01/03/some-specifics-on-generics.aspx#comments</comments><description>&lt;p&gt;&lt;/p&gt; &lt;p&gt;Generics are the most significant language addition to .NET 2.0. They allow for code re-use in ways not previously available and make it much easier to write type-safe, better performing code. That is, they help you turn runtime exceptions into compile-time errors while making your application run faster. Sound good?  &lt;p&gt;&lt;strong&gt;What’s the Problem?&lt;/strong&gt;&lt;br /&gt;The classic example used to demonstrate the problem Generics solve is the general purpose collection. In .NET 1.1 collection classes like the ArrayList and HashTable are object based so they can store data of any type. Unfortunately this benefit has a cost, the lack of type safety. The user of the ArrayList cannot restrict the types it stores, which can potentially lead to runtime errors.&lt;/p&gt; &lt;p&gt; &lt;div style="font-size:110%;color:black;font-family:consolas, lucida console, courier new;background-color:#eeeeee;"&gt;&lt;pre style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;Dim&lt;/span&gt; al &lt;span style="color:blue;"&gt;As&lt;/span&gt; &lt;span style="color:blue;"&gt;New&lt;/span&gt; ArrayList()&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;al.Add(11)&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;al.Add(42)&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;al.Add(18.0)&amp;nbsp; &lt;span style="color:green;"&gt;&amp;#39; will cause a runtime error in the for loop&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;Dim&lt;/span&gt; sum &lt;span style="color:blue;"&gt;As&lt;/span&gt; &lt;span style="color:blue;"&gt;Integer&lt;/span&gt; = 0&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;For&lt;/span&gt; i &lt;span style="color:blue;"&gt;As&lt;/span&gt; &lt;span style="color:blue;"&gt;Integer&lt;/span&gt; = 0 &lt;span style="color:blue;"&gt;To&lt;/span&gt; al.Count&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; sum += &lt;span style="color:blue;"&gt;CInt&lt;/span&gt;(al(i))&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;Next&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;
&lt;div style="font-size:110%;color:black;font-family:consolas, lucida console, courier new;background-color:#eeeeee;"&gt;&lt;pre style="margin:0px;"&gt;ArrayList al = &lt;span style="color:blue;"&gt;new&lt;/span&gt; ArrayList();&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;al.Add(11);&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;al.Add(42);&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;al.Add(18.0);&amp;nbsp; &lt;span style="color:green;"&gt;// will cause a runtime error in the for loop&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;int&lt;/span&gt; sum = 0;&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;for&lt;/span&gt; (&lt;span style="color:blue;"&gt;int&lt;/span&gt; i = 0; i &amp;lt; al.Count; i++) { sum += (&lt;span style="color:blue;"&gt;int&lt;/span&gt;)al&lt;img src="http://msmvps.com/emoticons/emotion-55.gif" alt="Idea" /&gt;; }&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The solution to this problem in .NET 1.1 is to create a strongly-type collection class by inheriting from CollectionBase (or DictionaryBase is you want HashTable like functionality). While this task is not difficult it is tedious and leads to code bloat. You have to write almost exactly the same code for each and every type which requires a strongly-typed collection.&lt;/p&gt;
&lt;p&gt;
&lt;div style="font-size:110%;color:black;font-family:consolas, lucida console, courier new;background-color:#eeeeee;"&gt;&lt;pre style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;Public&lt;/span&gt; &lt;span style="color:blue;"&gt;Class&lt;/span&gt; IntCollection&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;Inherits&lt;/span&gt; CollectionBase&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;Default&lt;/span&gt; &lt;span style="color:blue;"&gt;Public&lt;/span&gt; &lt;span style="color:blue;"&gt;Property&lt;/span&gt; Item(&lt;span style="color:blue;"&gt;ByVal&lt;/span&gt; index &lt;span style="color:blue;"&gt;As&lt;/span&gt; &lt;span style="color:blue;"&gt;Integer&lt;/span&gt;) &lt;span style="color:blue;"&gt;As&lt;/span&gt; &lt;span style="color:blue;"&gt;Integer&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;Get&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;Return&lt;/span&gt; (&lt;span style="color:blue;"&gt;CType&lt;/span&gt;(List(index), &lt;span style="color:blue;"&gt;Integer&lt;/span&gt;))&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;End&lt;/span&gt; &lt;span style="color:blue;"&gt;Get&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;Set&lt;/span&gt;(&lt;span style="color:blue;"&gt;ByVal&lt;/span&gt; Value &lt;span style="color:blue;"&gt;As&lt;/span&gt; &lt;span style="color:blue;"&gt;Integer&lt;/span&gt;)&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; List(index) = Value&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;End&lt;/span&gt; &lt;span style="color:blue;"&gt;Set&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;End&lt;/span&gt; &lt;span style="color:blue;"&gt;Property&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;Public&lt;/span&gt; &lt;span style="color:blue;"&gt;Function&lt;/span&gt; Add(&lt;span style="color:blue;"&gt;ByVal&lt;/span&gt; value &lt;span style="color:blue;"&gt;As&lt;/span&gt; &lt;span style="color:blue;"&gt;Integer&lt;/span&gt;) &lt;span style="color:blue;"&gt;As&lt;/span&gt; &lt;span style="color:blue;"&gt;Integer&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;Return&lt;/span&gt; (List.Add(value))&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;End&lt;/span&gt; &lt;span style="color:blue;"&gt;Function&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;Public&lt;/span&gt; &lt;span style="color:blue;"&gt;Function&lt;/span&gt; IndexOf(&lt;span style="color:blue;"&gt;ByVal&lt;/span&gt; value &lt;span style="color:blue;"&gt;As&lt;/span&gt; &lt;span style="color:blue;"&gt;Integer&lt;/span&gt;) &lt;span style="color:blue;"&gt;As&lt;/span&gt; &lt;span style="color:blue;"&gt;Integer&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;Return&lt;/span&gt; (List.IndexOf(value))&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;End&lt;/span&gt; &lt;span style="color:blue;"&gt;Function&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;Public&lt;/span&gt; &lt;span style="color:blue;"&gt;Sub&lt;/span&gt; Insert(&lt;span style="color:blue;"&gt;ByVal&lt;/span&gt; index &lt;span style="color:blue;"&gt;As&lt;/span&gt; &lt;span style="color:blue;"&gt;Integer&lt;/span&gt;, &lt;span style="color:blue;"&gt;ByVal&lt;/span&gt; value &lt;span style="color:blue;"&gt;As&lt;/span&gt; &lt;span style="color:blue;"&gt;Integer&lt;/span&gt;)&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; List.Insert(index, value)&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;End&lt;/span&gt; &lt;span style="color:blue;"&gt;Sub&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;Public&lt;/span&gt; &lt;span style="color:blue;"&gt;Sub&lt;/span&gt; Remove(&lt;span style="color:blue;"&gt;ByVal&lt;/span&gt; value &lt;span style="color:blue;"&gt;As&lt;/span&gt; &lt;span style="color:blue;"&gt;Integer&lt;/span&gt;)&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; List.Remove(value)&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;End&lt;/span&gt; &lt;span style="color:blue;"&gt;Sub&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;End&lt;/span&gt; &lt;span style="color:blue;"&gt;Class&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;
&lt;div style="font-size:110%;color:black;font-family:consolas, lucida console, courier new;background-color:#eeeeee;"&gt;&lt;pre style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span style="color:teal;"&gt;IntCollection&lt;/span&gt; : CollectionBase&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;{&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;int&lt;/span&gt; &lt;span style="color:blue;"&gt;this&lt;/span&gt;[&lt;span style="color:blue;"&gt;int&lt;/span&gt; index]&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; {&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;get&lt;/span&gt; { &lt;span style="color:blue;"&gt;return&lt;/span&gt; ((&lt;span style="color:blue;"&gt;int&lt;/span&gt;)List[index]); }&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;set&lt;/span&gt; { List[index] = &lt;span style="color:blue;"&gt;value&lt;/span&gt;; }&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; }&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;int&lt;/span&gt; Add(&lt;span style="color:blue;"&gt;int&lt;/span&gt; value)&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; {&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;return&lt;/span&gt; (List.Add(value));&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; }&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;int&lt;/span&gt; IndexOf(&lt;span style="color:blue;"&gt;int&lt;/span&gt; value)&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; {&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;return&lt;/span&gt; (List.IndexOf(value));&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; }&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; Insert(&lt;span style="color:blue;"&gt;int&lt;/span&gt; index, &lt;span style="color:blue;"&gt;int&lt;/span&gt; value)&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; {&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; List.Insert(index, value);&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; }&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; Remove(&lt;span style="color:blue;"&gt;int&lt;/span&gt; value)&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; {&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; List.Remove(value);&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; }&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;}&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;A second problem is performance. Value types need to be boxed when being added to the collection and the unboxed when they are retrieved. This is a “double whammy” because not only do you pay the penalty for boxing but you also add more and more work to the garbage collection mechanism as the collection grows. Even if you’re storing reference types there is still some penalty for casting. 
&lt;p&gt;&lt;strong&gt;Using Generics&lt;br /&gt;&lt;/strong&gt;Generics are designed to address the issues stated above without sacrificing developer productivity. The idea is to allow classes to be parameterized by the types they store and manipulate. The type parameter or parameters, which are enclosed in angle brackets and separated by commas, can be added to a class or method declaration. The type parameter acts as a placeholder for the actual type that will be used at runtime. For example you could create a generic Stack class: 
&lt;p&gt;
&lt;div style="font-size:110%;color:black;font-family:consolas, lucida console, courier new;background-color:#eeeeee;"&gt;&lt;pre style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;Public&lt;/span&gt; &lt;span style="color:blue;"&gt;Class&lt;/span&gt; Stack(&lt;span style="color:blue;"&gt;Of&lt;/span&gt; T)&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;Private&lt;/span&gt; _items &lt;span style="color:blue;"&gt;As&lt;/span&gt; &lt;span style="color:blue;"&gt;New&lt;/span&gt; List(&lt;span style="color:blue;"&gt;Of&lt;/span&gt; T)&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;Public&lt;/span&gt; &lt;span style="color:blue;"&gt;Sub&lt;/span&gt; Push(&lt;span style="color:blue;"&gt;ByVal&lt;/span&gt; item &lt;span style="color:blue;"&gt;As&lt;/span&gt; T)&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; _items.Add(item)&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;End&lt;/span&gt; &lt;span style="color:blue;"&gt;Sub&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;Public&lt;/span&gt; &lt;span style="color:blue;"&gt;Function&lt;/span&gt; Pop() &lt;span style="color:blue;"&gt;As&lt;/span&gt; T&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;If&lt;/span&gt; _items.Count = 0 &lt;span style="color:blue;"&gt;Then&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;Throw&lt;/span&gt; &lt;span style="color:blue;"&gt;New&lt;/span&gt; InvalidOperationException(&lt;span style="color:maroon;"&gt;&amp;quot;Stack is empty&amp;quot;&lt;/span&gt;)&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;End&lt;/span&gt; &lt;span style="color:blue;"&gt;If&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;Dim&lt;/span&gt; index &lt;span style="color:blue;"&gt;As&lt;/span&gt; &lt;span style="color:blue;"&gt;Integer&lt;/span&gt; = _items.Count - 1&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;Dim&lt;/span&gt; item &lt;span style="color:blue;"&gt;As&lt;/span&gt; T = _items(index)&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; _items.RemoveAt(index)&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;Return&lt;/span&gt; item&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;End&lt;/span&gt; &lt;span style="color:blue;"&gt;Function&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;End&lt;/span&gt; &lt;span style="color:blue;"&gt;Class&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;
&lt;div style="font-size:110%;color:black;font-family:consolas, lucida console, courier new;background-color:#eeeeee;"&gt;&lt;pre style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span style="color:teal;"&gt;Stack&lt;/span&gt;&amp;lt;T&amp;gt; {&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;private&lt;/span&gt; &lt;span style="color:teal;"&gt;List&lt;/span&gt;&amp;lt;T&amp;gt; _items = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:teal;"&gt;List&lt;/span&gt;&amp;lt;T&amp;gt;();&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; Push(T item) { _items.Add(item); }&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; T Pop() {&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;if&lt;/span&gt; (_items.Count == 0) {&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;throw&lt;/span&gt; &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:teal;"&gt;InvalidOperationException&lt;/span&gt;(“Stack &lt;span style="color:blue;"&gt;is&lt;/span&gt; empty”);&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;int&lt;/span&gt; index = _items.Count – 1;&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; T item = _items[index];&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; _items.RemoveAt(index);&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;return&lt;/span&gt; item;&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; }&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;}&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In this case the type parameter is &lt;strong&gt;T&lt;/strong&gt; (it is common practice to use a single capital letter as the name for a type parameter but you are free to use more descriptive names if you choose) so the type would be know as “Stack of T”. T is used as the type for the regular parameter to Push and the return type of Pop. It is interesting to note that it is also used as the type argument in the construction of the internal List of items. The type argument defines the specific type you wish to use for that instance of the generic class. 
&lt;p&gt;The .NET Framework 2.0 adds several new generic collection classes in the System.Collections.Generic namespace, the most commonly used being List&amp;lt;T&amp;gt; (the generic version of ArrayList) and Dictionary&amp;lt;K, T&amp;gt; (the generic version of HashTable). 
&lt;p&gt;
&lt;div style="font-size:110%;color:black;font-family:consolas, lucida console, courier new;background-color:#eeeeee;"&gt;&lt;pre style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;Dim&lt;/span&gt; al &lt;span style="color:blue;"&gt;As&lt;/span&gt; &lt;span style="color:blue;"&gt;New&lt;/span&gt; List(&lt;span style="color:blue;"&gt;Of&lt;/span&gt; &lt;span style="color:blue;"&gt;Integer&lt;/span&gt;)&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;al.Add(11)&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;al.Add(42)&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;al.Add(18.0)&amp;nbsp; &lt;span style="color:green;"&gt;&amp;#39; will cause a complie time error&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;Dim&lt;/span&gt; sum &lt;span style="color:blue;"&gt;As&lt;/span&gt; &lt;span style="color:blue;"&gt;Integer&lt;/span&gt; = 0&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;For&lt;/span&gt; i &lt;span style="color:blue;"&gt;As&lt;/span&gt; &lt;span style="color:blue;"&gt;Integer&lt;/span&gt; = 0 &lt;span style="color:blue;"&gt;To&lt;/span&gt; al.Count&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; sum += al(i)&amp;nbsp; &lt;span style="color:green;"&gt;&amp;#39; no cast or unboxing required&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;Next&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;
&lt;div style="font-size:110%;color:black;font-family:consolas, lucida console, courier new;background-color:#eeeeee;"&gt;&lt;pre style="margin:0px;"&gt;&lt;span style="color:teal;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt; al = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:teal;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt;();&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;al.Add(11);&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;al.Add(42);&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;al.Add(18.0);&amp;nbsp; &lt;span style="color:green;"&gt;//will cause a complie time error&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;int&lt;/span&gt; sum = 0;&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;for&lt;/span&gt; (&lt;span style="color:blue;"&gt;int&lt;/span&gt; i = 0; i &amp;lt; al.Count; i++) { &lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; sum += al&lt;img src="http://msmvps.com/emoticons/emotion-55.gif" alt="Idea" /&gt;; &lt;span style="color:green;"&gt;// no cast or unboxing required&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;}&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Generic Methods&lt;br /&gt;&lt;/strong&gt;You have seen adding type parameters to classes, you can do the same thing for methods. This can be done even if the class itself is not generic. To do this you use the same syntax style as with classes, adding the type parameter after the name of the method but before the regular parameter list. 
&lt;p&gt;
&lt;div style="font-size:110%;color:black;font-family:consolas, lucida console, courier new;background-color:#eeeeee;"&gt;&lt;pre style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;Private&lt;/span&gt; &lt;span style="color:blue;"&gt;Class&lt;/span&gt; Utility&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;Public&lt;/span&gt; &lt;span style="color:blue;"&gt;Function&lt;/span&gt; Max(&lt;span style="color:blue;"&gt;Of&lt;/span&gt; T)(&lt;span style="color:blue;"&gt;ByVal&lt;/span&gt; a &lt;span style="color:blue;"&gt;As&lt;/span&gt; T, &lt;span style="color:blue;"&gt;ByVal&lt;/span&gt; b &lt;span style="color:blue;"&gt;As&lt;/span&gt; T) &lt;span style="color:blue;"&gt;As&lt;/span&gt; T&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;If&lt;/span&gt; a &amp;gt; b &lt;span style="color:blue;"&gt;Then&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;Return&lt;/span&gt; a&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;End&lt;/span&gt; &lt;span style="color:blue;"&gt;If&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;Return&lt;/span&gt; b&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;End&lt;/span&gt; &lt;span style="color:blue;"&gt;Function&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;End&lt;/span&gt; &lt;span style="color:blue;"&gt;Class&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&lt;span style="color:green;"&gt;&amp;#39; usage of Max&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;Public&lt;/span&gt; &lt;span style="color:blue;"&gt;Sub&lt;/span&gt; MaxTest()&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;Dim&lt;/span&gt; u &lt;span style="color:blue;"&gt;As&lt;/span&gt; &lt;span style="color:blue;"&gt;New&lt;/span&gt; Utility()&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;Dim&lt;/span&gt; i &lt;span style="color:blue;"&gt;As&lt;/span&gt; &lt;span style="color:blue;"&gt;Integer&lt;/span&gt; = u.Max(&lt;span style="color:blue;"&gt;Of&lt;/span&gt; &lt;span style="color:blue;"&gt;Integer&lt;/span&gt;)(7, 11)&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:green;"&gt;&amp;#39; Use type inference&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;Dim&lt;/span&gt; d &lt;span style="color:blue;"&gt;As&lt;/span&gt; &lt;span style="color:blue;"&gt;Double&lt;/span&gt; = u.Max(10.0, 42.42)&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;End&lt;/span&gt; &lt;span style="color:blue;"&gt;Sub&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;
&lt;p&gt;
&lt;div style="font-size:110%;color:black;font-family:consolas, lucida console, courier new;background-color:#eeeeee;"&gt;&lt;pre style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;private&lt;/span&gt; &lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span style="color:teal;"&gt;Utility&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;{&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; T Max&amp;lt;T&amp;gt;(T a, T b)&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; {&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;if&lt;/span&gt; (a &amp;gt; b) { &lt;span style="color:blue;"&gt;return&lt;/span&gt; a; }&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;return&lt;/span&gt; b;&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; }&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;}&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&lt;span style="color:green;"&gt;// usage of Max&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; MaxTest()&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;{&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:teal;"&gt;Utility&lt;/span&gt; u = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:teal;"&gt;Utility&lt;/span&gt;();&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;int&lt;/span&gt; i = u.Max&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt;(7, 11);&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;double&lt;/span&gt; d = u.Max(10.0, 42.42);&amp;nbsp; &lt;span style="color:green;"&gt;//OK, uses type inference&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;}&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;When using generic methods, the C# compiler is able to infer the type arguments from the types of the regular parameters passed so you do not have to explicitly state them. 
&lt;p&gt;&lt;strong&gt;Constraints&lt;/strong&gt;&lt;br /&gt;Time to “fess up”, the code for the Max method in the example directly above does not compile. The condition (a &amp;gt; b) causes a compiler error because it does not have meaning for all possible values of T. To get it to work you need to modify the code somewhat. 
&lt;p&gt;
&lt;div style="font-size:110%;color:black;font-family:consolas, lucida console, courier new;background-color:#eeeeee;"&gt;&lt;pre style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;Public&lt;/span&gt; &lt;span style="color:blue;"&gt;Class&lt;/span&gt; Utility&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;Public&lt;/span&gt; &lt;span style="color:blue;"&gt;Function&lt;/span&gt; Max(&lt;span style="color:blue;"&gt;Of&lt;/span&gt; T)(&lt;span style="color:blue;"&gt;ByVal&lt;/span&gt; a &lt;span style="color:blue;"&gt;As&lt;/span&gt; T, &lt;span style="color:blue;"&gt;ByVal&lt;/span&gt; b &lt;span style="color:blue;"&gt;As&lt;/span&gt; T)&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;If&lt;/span&gt; a.CompareTo(b) &amp;gt; 0 &lt;span style="color:blue;"&gt;Then&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;Return&lt;/span&gt; a&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;End&lt;/span&gt; &lt;span style="color:blue;"&gt;If&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;Return&lt;/span&gt; b&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;End&lt;/span&gt; &lt;span style="color:blue;"&gt;Function&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;End&lt;/span&gt; &lt;span style="color:blue;"&gt;Class&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;
&lt;div style="font-size:110%;color:black;font-family:consolas, lucida console, courier new;background-color:#eeeeee;"&gt;&lt;pre style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span style="color:teal;"&gt;Utility&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;{&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; T Max&amp;lt;T&amp;gt;(T a, T b)&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; {&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;if&lt;/span&gt; (a.CompareTo(b) &amp;gt; 0) { &lt;span style="color:blue;"&gt;return&lt;/span&gt; a; }&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;return&lt;/span&gt; b;&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; }&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;}&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;OK, it still doesn’t compile. Using CompareTo is a valid solution but it requires that the type assigned to T implement the IComparable interface. You need to indicate this constraint to the C# compiler. This requires one additional code change.&lt;/p&gt;
&lt;p&gt;
&lt;div style="font-size:110%;color:black;font-family:consolas, lucida console, courier new;background-color:#eeeeee;"&gt;&lt;pre style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;Public&lt;/span&gt; &lt;span style="color:blue;"&gt;Class&lt;/span&gt; Utility&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;Public&lt;/span&gt; &lt;span style="color:blue;"&gt;Function&lt;/span&gt; Max(&lt;span style="color:blue;"&gt;Of&lt;/span&gt; T &lt;span style="color:blue;"&gt;As&lt;/span&gt; IComparable(&lt;span style="color:blue;"&gt;Of&lt;/span&gt; T)) _&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;span style="color:blue;"&gt;ByVal&lt;/span&gt; a &lt;span style="color:blue;"&gt;As&lt;/span&gt; T, &lt;span style="color:blue;"&gt;ByVal&lt;/span&gt; b &lt;span style="color:blue;"&gt;As&lt;/span&gt; T)&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;If&lt;/span&gt; a.CompareTo(b) &amp;gt; 0 &lt;span style="color:blue;"&gt;Then&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;Return&lt;/span&gt; a&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;End&lt;/span&gt; &lt;span style="color:blue;"&gt;If&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;Return&lt;/span&gt; b&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;End&lt;/span&gt; &lt;span style="color:blue;"&gt;Function&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;End&lt;/span&gt; &lt;span style="color:blue;"&gt;Class&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;
&lt;div style="font-size:110%;color:black;font-family:consolas, lucida console, courier new;background-color:#eeeeee;"&gt;&lt;pre style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span style="color:teal;"&gt;Utility&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;{&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; T Max&amp;lt;T&amp;gt;(T a, T b) &lt;span style="color:blue;"&gt;where&lt;/span&gt; T : &lt;span style="color:teal;"&gt;IComparable&lt;/span&gt;&amp;lt;T&amp;gt; &lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; {&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;if&lt;/span&gt; (a.CompareTo(b) &amp;gt; 0) { &lt;span style="color:blue;"&gt;return&lt;/span&gt; a; }&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;return&lt;/span&gt; b;&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; }&lt;/pre&gt;&lt;pre style="margin:0px;"&gt;}&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Other common constraints are: requiring a particular base type for the type argument, indicating that the type argument must be a reference type or value type, and indicating that the type argument must have a default constructor.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br /&gt;Generics are better for you than Broccoli (assuming that easier to write, type-safe, performant code is important to you, if not the please do a Google search for Ruby to find material more to your taste). As you work with&amp;nbsp;.NET 2.0 you will begin to get the “Zen of Generics” and then you will see that the immediate benefits of strongly-typed collections are really just the tip of the Iceberg&amp;lt;T&amp;gt; where T : Big, ICold. &lt;/p&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=466635" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/windsor/archive/tags/Development/default.aspx">Development</category><category domain="http://msmvps.com/blogs/windsor/archive/tags/Article/default.aspx">Article</category><category domain="http://msmvps.com/blogs/windsor/archive/tags/Generics/default.aspx">Generics</category><category domain="http://msmvps.com/blogs/windsor/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/windsor/archive/tags/DevCenter/default.aspx">DevCenter</category><category domain="http://msmvps.com/blogs/windsor/archive/tags/VB/default.aspx">VB</category></item><item><title>Keep Client Applications Responsive with the BackgroundWorker</title><link>http://msmvps.com/blogs/windsor/archive/2006/11/09/Keep-Client-Applications-Responsive-with-the-BackgroundWorker.aspx</link><pubDate>Thu, 09 Nov 2006 09:58:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:269466</guid><dc:creator>windsor</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/windsor/rsscomments.aspx?PostID=269466</wfw:commentRss><comments>http://msmvps.com/blogs/windsor/archive/2006/11/09/Keep-Client-Applications-Responsive-with-the-BackgroundWorker.aspx#comments</comments><description>&lt;p&gt;Many applications need to perform some kind of long-running task like downloading a file, performing a complex calculation, or retrieving data from a database. Executing these tasks can make your application become unresponsive and end up making your users anxious. Take too long performing the task and the user will be looking for the Task Manager to kill your application. &lt;/p&gt;&lt;p&gt;The solution to this problem is to execute the long-running task on a second (or background) thread. This allows the user interface thread to continue working keeping your application responsive, but it presents you with a new problem. Creating multi-threaded applications is difficult - well actually it&amp;rsquo;s easy - it&amp;rsquo;s doing so properly, following all the rules, and not coding yourself into an all night debugging session that&amp;rsquo;s truly hard. &lt;/p&gt;&lt;p&gt;To help address this issue Microsoft added the BackgroundWorker component to .NET 2.0. This component is easy to use and understand and makes programming multi-threaded applications (without explicitly creating and managing threads) much safer for the developer. The exploration of the BackgroundWorker will be done through the creation of a demo application. &lt;/p&gt;&lt;p&gt;For a more comprehensive discussion of the topics covered in this article and to see how to achieve the same results using previous versions of .NET, see Chris Sells three-part series entitled Safe, Simple Multithreading in Windows Forms (&lt;a href="http://shrinkster.com/ddm"&gt;http://shrinkster.com/ddm&lt;/a&gt;). &lt;/p&gt;&lt;p&gt;Let&amp;#39;s assume you have a simple application with a Button and a ProgressBar. The&amp;nbsp;code below&amp;nbsp;will simulate a long-running task by putting the user interface thread to sleep, one half second at a time, in a loop. The loop is used to allow the program to report progress back to the user via&amp;nbsp;the ProgressBar. &lt;/p&gt;&lt;p&gt;&lt;font face="Lucida Console"&gt;Private Sub Button1_Click(...) Handles Button1.Click&lt;br /&gt;&amp;nbsp; Button1.Enabled = False&lt;br /&gt;&amp;nbsp; For i As Integer = 1 To 10&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ProgressBar1.Value = i * 10&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Threading.Thread.Sleep(500)&lt;br /&gt;&amp;nbsp; Next&lt;br /&gt;&amp;nbsp; MessageBox.Show(&amp;quot;Done&amp;quot;, &amp;quot;Demo&amp;quot;)&lt;br /&gt;&amp;nbsp; Button1.Enabled = True&lt;br /&gt;End Sub&lt;/font&gt; &lt;/p&gt;&lt;p&gt;As it stands, clicking the Start Button will begin the long-running task and, while the ProgressBar will be updated as we iterate through the loop, the rest of the application will be unresponsive. You will not be able to move or resize the form until the loop completes. The remainder of this&amp;nbsp;post will discuss how to convert this code to run the loop on a background thread via the BackgroundWorker component. It will also show how to upgrade the application to allow the long-running task to be cancelled. &lt;/p&gt;&lt;p&gt;First, declare a private field for the BackgroundWorker. Then in the Form&amp;rsquo;s Load event handler, create the instance of the BackgroundWorker and set its WorkerReportsProgress and WorkerSupportsCancellation properties to True. These properties are set to False by default as a performance optimization. &lt;/p&gt;&lt;p&gt;&lt;font face="Lucida Console"&gt;Private WithEvents _worker As BackgroundWorker&lt;br /&gt;Private _working As Boolean&lt;br /&gt;Private Sub Form1_Load(...) Handles MyBase.Load&lt;br /&gt;&amp;nbsp; _worker = New BackgroundWorker&lt;br /&gt;&amp;nbsp; _worker.WorkerReportsProgress = True&lt;br /&gt;&amp;nbsp; _worker. WorkerSupportsCancellation = True&lt;br /&gt;End Sub&lt;/font&gt; &lt;/p&gt;&lt;p&gt;Create an event hander for the BackgroundWorker&amp;rsquo;s DoWork event and copy the existing code from the Button&amp;rsquo;s Click event hander to the newly created method. The Button is going to be used to both start the long-running task as well as cancel it. In the Click event handler check if the BackgroundWorker is currently busy; if it is signal a request to cancel the task by calling CancelAsync otherwise begin the task by calling RunWorkerAsync. It is important to note that the call to CancelAsync does not immediately terminate the task, it just signals a request to cancel. The code running the task must check for the request and handle it appropriately (see below).&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;font face="Lucida Console"&gt;Private Sub Button1_Click(...) Handles Button1.Click&lt;br /&gt;&amp;nbsp; If _worker.IsBusy Then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; _worker.CancelAsync()&lt;br /&gt;&amp;nbsp; Else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Button1.Text = &amp;quot;Cancel&amp;quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; _worker.RunWorkerAsync()&lt;br /&gt;&amp;nbsp; End If&lt;br /&gt;End Sub&lt;/font&gt; &lt;/p&gt;&lt;p&gt;The code copied to the DoWork event handler needs to be modified slightly. The code in this event handler executes on a background thread so it cannot safely update the user interface, thus the line that originally set the Value property of the ProgressBar has to be changed. Replace this line with a call to the ReportProgress method of the BackgroundWorker passing the percent completed as a parameter. This will trigger the ProgressChanged event where we can safely update the ProgressBar. In addition, this code has to check for a request from the user to cancel the task which can be done by inspecting the CancellationPending property of the BackgroundWorker. &lt;/p&gt;&lt;p&gt;&lt;font face="Lucida Console"&gt;Private Sub _worker_DoWork(...) Handles _worker.DoWork&lt;br /&gt;&amp;nbsp; For i As Integer = 1 To 10&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; _worker.ReportProgress(i * 10)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Threading.Thread.Sleep(500)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; If _worker.CancellationPending Then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; e.Cancel = True&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Exit For&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; End If&lt;br /&gt;&amp;nbsp; Next&lt;br /&gt;End Sub &lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font face="Lucida Console"&gt;Private Sub _worker_ProgressChanged(...) &lt;/font&gt;&lt;font face="Lucida Console"&gt;Handles _worker.ProgressChanged&lt;br /&gt;&amp;nbsp; ProgressBar1.Value = e.ProgressPercentage&lt;br /&gt;End Sub&lt;/font&gt; &lt;/p&gt;&lt;p&gt;Finally, the BackgroundWorker raises the RunWorkerCompleted event to notify the user interface that long-running task is done, either because it completed normally or because it was cancelled. &lt;/p&gt;&lt;p&gt;&lt;font face="Lucida Console"&gt;Private Sub _worker_RunWorkerCompleted(...) Handles _worker.RunWorkerCompleted&lt;br /&gt;&amp;nbsp; Dim msg As String = &amp;quot;Done&amp;quot;&lt;br /&gt;&amp;nbsp; If e.Cancelled Then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; msg = &amp;quot;Cancelled&amp;quot;&lt;br /&gt;&amp;nbsp; End If&lt;br /&gt;&amp;nbsp; Button1.Text = &amp;quot;Start&amp;quot;&lt;br /&gt;&amp;nbsp; MessageBox.Show(msg, &amp;quot;Demo&amp;quot;)&lt;br /&gt;End Sub&lt;/font&gt; &lt;/p&gt;&lt;p&gt;This short example demonstrates the basic use of the BackgroundWorker. That is executing a long-running task on a background thread, showing progress, and allowing the user to cancel.&lt;/p&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=269466" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/windsor/archive/tags/Development/default.aspx">Development</category><category domain="http://msmvps.com/blogs/windsor/archive/tags/Article/default.aspx">Article</category><category domain="http://msmvps.com/blogs/windsor/archive/tags/Smart+Client/default.aspx">Smart Client</category><category domain="http://msmvps.com/blogs/windsor/archive/tags/DevCenter/default.aspx">DevCenter</category><category domain="http://msmvps.com/blogs/windsor/archive/tags/VB/default.aspx">VB</category></item></channel></rss>