<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>.NET</title>
        <link>http://geekswithblogs.net/tonyt/category/4059.aspx</link>
        <description>Topics related to .NET technologies.</description>
        <language>en-US</language>
        <copyright>Anthony Trudeau</copyright>
        <managingEditor>agrt.home@hotmail.com</managingEditor>
        <generator>Subtext Version 0.0.0.0</generator>
        <item>
            <title>Unit testing on events</title>
            <link>http://geekswithblogs.net/tonyt/archive/2008/06/26/123403.aspx</link>
            <description>&lt;p&gt;Here's a little method I came up with recently to test the execution of events.  You may not ever need to test to see that an event fires, because you have some other state that you can check.  However, that is not always the case.  Here is how I approached it using the unit testing provided with the developer's team editon of Visual Studio.&lt;/p&gt;
&lt;p&gt;The first thing I did was add a wait handle object inside the definition of my unit test class.  Specifically, I chose a ManualResetEvent for the most control, but other types of wait handles may work fine.&lt;/p&gt;
&lt;div style="FONT-SIZE: 11pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Consolas"&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;ManualResetEvent&lt;/span&gt; _waitHandle;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The next step was to add code for the class initialize and cleanup methods.  I need to create my wait handle and after I finish running my tests I want to make sure that I release any resources tied-up by the wait handle.  Additionally, after a test is run I want to make sure that the wait handle is in an unsignalled state.  Therefore, I need to provide a test cleanup method.&lt;/p&gt;
&lt;div style="FONT-SIZE: 11pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Consolas"&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: green"&gt;//Use ClassInitialize to run code before running the first test&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        [&lt;span style="COLOR: #2b91af"&gt;ClassInitialize&lt;/span&gt;()]&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; MyClassInitialize(&lt;span style="COLOR: #2b91af"&gt;TestContext&lt;/span&gt; testContext)&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            _waitHandle = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;ManualResetEvent&lt;/span&gt;(&lt;span style="COLOR: blue"&gt;false&lt;/span&gt;);&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: green"&gt;//Use ClassCleanup to run code after all tests in a class have run&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        [&lt;span style="COLOR: #2b91af"&gt;ClassCleanup&lt;/span&gt;()]&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; MyClassCleanup()&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (_waitHandle != &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;)&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;                _waitHandle.Close();&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt; &lt;/p&gt;
&lt;/div&gt;
&lt;div style="FONT-SIZE: 11pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Consolas"&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: green"&gt;//Use TestCleanup to run code after each test has run&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        [&lt;span style="COLOR: #2b91af"&gt;TestCleanup&lt;/span&gt;()]&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; MyTestCleanup()&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            _waitHandle.Reset();&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;That's pretty much it except for the logic in the code itself.  In that code, you create your event handler, run the action that will trigger the event, and then wait for the ManualResetEvent to be signalled.  It is advisable to provide an arbitrary yet realistic value for a timeout so that your test doesn't run forever if the event isn't fired.&lt;/p&gt;
&lt;div style="FONT-SIZE: 11pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Consolas"&gt;
&lt;p style="MARGIN: 0px"&gt;        [&lt;span style="COLOR: #2b91af"&gt;TestMethod&lt;/span&gt;()]&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; EventExecutedTest()&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            &lt;span style="COLOR: #2b91af"&gt;MyObject &lt;/span&gt;target = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;MyObject&lt;/span&gt;();&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;           &lt;span style="COLOR: green"&gt;// TODO: add additional declarations as needed for test&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            target.EventExecuted += (sender, e) =&amp;gt; _waitHandle.Set();&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;           &lt;span style="COLOR: green"&gt;// TODO: perform actions that need to trigger the event&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            &lt;span style="COLOR: blue"&gt;bool&lt;/span&gt; result = _waitHandle.WaitOne(3000, &lt;span style="COLOR: blue"&gt;true&lt;/span&gt;);&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;            &lt;span style="COLOR: #2b91af"&gt;Assert&lt;/span&gt;.IsTrue(result);                                  &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;        }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt; As you can see there's not too much to it.  This is a simple mechanism to unit tests events when it makes sense.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=123403"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=123403" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/tonyt/aggbug/123403.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Anthony Trudeau</dc:creator>
            <guid>http://geekswithblogs.net/tonyt/archive/2008/06/26/123403.aspx</guid>
            <pubDate>Thu, 26 Jun 2008 12:52:18 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/tonyt/comments/123403.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/tonyt/archive/2008/06/26/123403.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/tonyt/comments/commentRss/123403.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/tonyt/services/trackbacks/123403.aspx</trackback:ping>
        </item>
        <item>
            <title>Infragistics support with SCSF -- April 2008</title>
            <link>http://geekswithblogs.net/tonyt/archive/2008/05/23/122345.aspx</link>
            <description>&lt;p&gt;I just recently installed the new version of the Smart Client Software Factory (SCSF) and wanted to utilize the Composite UI Application Block (CAB) support within my Infragistics components with it within Visual Studio 2008.  Luckily, the process is easy and these steps are all you have to do:&lt;/p&gt;
&lt;ol&gt;
    &lt;li&gt;Open Visual Studio 2008 &lt;/li&gt;
    &lt;li&gt;Open the Infragistics.CompositeUI.WinForms solution and allow the conversion &lt;/li&gt;
    &lt;li&gt;Add references to the following Microsoft libraries from the SCSF installation:
    &lt;ul&gt;
        &lt;li&gt;Microsoft.Practices.CompositeUI.dll &lt;/li&gt;
        &lt;li&gt;Microsoft.Practices.CompositeUI.Winforms.dll &lt;/li&gt;
        &lt;li&gt;Microsoft.Practices.ObjectBuilder.dll &lt;/li&gt;
    &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;Specify a key file for signing in the project settings if desired &lt;/li&gt;
    &lt;li&gt;Build the solution &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The Infragistics composite UI solution is located in the C:\Documents and Settings\All Users\Shared Documents\&lt;font face="Arial"&gt;Infragistics\NetAdvantage for .NET 2008 Vol. 1 CLR 2.0\&lt;font face="Arial"&gt;CAB Extensibility Kit folder (folder may vary based on the version of the Infragistics controls).  You must have at least 2008 Vol 1. controls.&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=122345"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=122345" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/tonyt/aggbug/122345.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Anthony Trudeau</dc:creator>
            <guid>http://geekswithblogs.net/tonyt/archive/2008/05/23/122345.aspx</guid>
            <pubDate>Fri, 23 May 2008 08:03:25 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/tonyt/comments/122345.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/tonyt/archive/2008/05/23/122345.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/tonyt/comments/commentRss/122345.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/tonyt/services/trackbacks/122345.aspx</trackback:ping>
        </item>
        <item>
            <title>Catching General Exceptions</title>
            <link>http://geekswithblogs.net/tonyt/archive/2008/04/26/121667.aspx</link>
            <description>&lt;p&gt;Probably all of us know now that you shouldn't catch general exceptions (CA1031).  There are practical reasons for this rule such as the fact that you really cannot handle an OutOfMemoryException or StackOverflowException for example.  Here is an example of catching a general exception for those that might not know what I'm talking about.&lt;/p&gt;
&lt;div style="FONT-SIZE: 11pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Consolas"&gt;
&lt;p style="MARGIN: 0px"&gt;   &lt;span style="COLOR: blue"&gt;try&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;   {&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;   }&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;   &lt;span style="COLOR: blue"&gt;catch&lt;/span&gt; (&lt;span style="COLOR: #2b91af"&gt;Exception&lt;/span&gt; ex)&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;   {&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;   } &lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;There are also more intrinsic design reasons why you shouldn't catch a general exception.  And if there is no other reason, if you're catching a general exception can you say you really know your code?  And if you don't know your code maybe it's time to step back and put a little more thought into what you're doing.&lt;/p&gt;
&lt;p&gt;But, wait, what if you know your code but the code your try block is nesting isn't known -- such as calling an abstract member within a base class?  Still, I say no general exceptions.  Its better to let the application come tumbling down then the possible side effects of catching and either handling or swallowing an exception that you really don't know how to properly handle.  Okay you say, what if its imperative that the application stay alive despite the possibility of ill-behaving code in a concrete class?  Fine you got me there, its time to catch the general exception -- with the caveat that you still need to properly handle the exception.&lt;/p&gt;
&lt;p&gt;How do you handle a general exception, because by its definition it could be virtually anything?  You really cannot, but you can handle quite a bit and remember that by virtue of this application that must have high reliability (be up all of the time).  When you have an application like that you probably have some type of service managing the class.  Therefore, what I do is add an event to my class called UnhandledException.&lt;/p&gt;
&lt;p&gt;The service class can subscribe to that event and choose to handle it or not via a Handled property on a concrete implementation of the EventArgs class.  With that in mind you just need to address your initial error handler and make sure that anything that isn't handled by the service class is then re-thrown which will and should take down the whole shebang.&lt;span style="COLOR: blue"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div style="FONT-SIZE: 11pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Consolas"&gt;
&lt;p style="MARGIN: 0px"&gt;   &lt;span style="COLOR: blue"&gt;try&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;   {&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;       &lt;span style="COLOR: green"&gt;// some process that can raise an unknown exception&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;   }&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;   &lt;span style="COLOR: blue"&gt;catch&lt;/span&gt; (&lt;span style="COLOR: #2b91af"&gt;Exception&lt;/span&gt; ex)&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;   {&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;       &lt;span style="COLOR: #2b91af"&gt;ExceptionEventArgs&lt;/span&gt; args = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;ExceptionEventArgs&lt;/span&gt;(ex);&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;       OnUnhandledException(args);&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;       &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (!args.Handled)&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;          &lt;span style="COLOR: blue"&gt;throw&lt;/span&gt;;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;   }&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt; &lt;/p&gt;
&lt;/div&gt;
&lt;p style="MARGIN: 0px"&gt;As you can see from this implementation we leave it up to the service class to determine what to do with the exception.  You still may have tasks to do with specific exceptions and in theses cases you should have blocks for those specific exceptions.  However, this cleanly delegates the work to the service allowing it to make the determination of what to do -- which may include tearing down and recycling the instance that raised the exception.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=121667"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=121667" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/tonyt/aggbug/121667.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Anthony Trudeau</dc:creator>
            <guid>http://geekswithblogs.net/tonyt/archive/2008/04/26/121667.aspx</guid>
            <pubDate>Sat, 26 Apr 2008 07:02:08 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/tonyt/comments/121667.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/tonyt/archive/2008/04/26/121667.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/tonyt/comments/commentRss/121667.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/tonyt/services/trackbacks/121667.aspx</trackback:ping>
        </item>
        <item>
            <title>Funny Little Logic Errors</title>
            <link>http://geekswithblogs.net/tonyt/archive/2008/03/10/120427.aspx</link>
            <description>&lt;p&gt;I received an email this morning from my manager saying that I need to look at this one utility, because it's showing a high CPU utilization and preventing another application from running.  The utility runs on a Terminal Server so the problem is exaserbated by multiple users in different sessions.&lt;/p&gt;
&lt;p&gt;Keep in mind that this utility has been in production for several months and there have been zero bug reports.  But, sure enough using the information I was able to duplicate the problem and based on the details of the problem I knew what function was causing the problem and I quickly saw the problem:&lt;/p&gt;
&lt;p&gt;&lt;!--
{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Consolas;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green128\blue0;\red0\green0\blue255;}??\fs22                 \cf3 // wait for a signal from AddRequest, ClearError, or the Stop method\par ??\cf0                 \cf4 if\cf0  (!_disposed)\par ??                    _waitHandle.WaitOne(timeout, \cf4 false\cf0 );}
--&gt;&lt;/p&gt;
&lt;div style="FONT-SIZE: 11pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Consolas"&gt;
&lt;p style="MARGIN: 0px"&gt;      &lt;span style="COLOR: green"&gt;// wait for a signal from AddRequest, ClearError, or the Stop method&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;      &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (_disposed)&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;          _waitHandle.WaitOne(timeout, &lt;span style="COLOR: blue"&gt;false&lt;/span&gt;);&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; A half a day of work lost, because I messed up the logic and should have said, "if (!_disposed)".  Oh well, it seems that no matter how well you think you test the code that there's always the possibility of something funny like this that you don't look for.  I feel comfortable saying that the utilty is still well tested since its not a trivial utility and I've only had one bug report.  But, I still feel like slapping myself for that funny little logic error.&lt;/p&gt;
&lt;p&gt;Anyone else do these funny little logic errors?&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=120427"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=120427" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/tonyt/aggbug/120427.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Anthony Trudeau</dc:creator>
            <guid>http://geekswithblogs.net/tonyt/archive/2008/03/10/120427.aspx</guid>
            <pubDate>Mon, 10 Mar 2008 08:48:37 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/tonyt/comments/120427.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/tonyt/archive/2008/03/10/120427.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/tonyt/comments/commentRss/120427.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/tonyt/services/trackbacks/120427.aspx</trackback:ping>
        </item>
        <item>
            <title>Overview of custom attributes</title>
            <link>http://geekswithblogs.net/tonyt/archive/2008/01/16/118612.aspx</link>
            <description>&lt;p&gt;Attributes are elements of metadata that you can attach to entities such as assemblies, classes, methods, properties, et al.  The .NET Framework makes use of many attributes that allow you to affect the behavior of the compiler or how the Framework uses an entity.  For example, you can assign attributes to properties of a control object that allow a friendly  name and description to be shown in the property browser in Visual Studio.&lt;/p&gt;
&lt;p&gt;At some point, you'll come into a situation where you'll want to use a custom attribute.  Defining and using attributes are very easy and in this article I will provide a very simple setup using a few attributes defined at the class level.  Defining and using attributes at other levels vary only slightly and I'll make note when there is a difference.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geekswithblogs.net/tonyt/archive/2008/01/16/118611.aspx"&gt;Read the rest of the article&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=118612"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=118612" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/tonyt/aggbug/118612.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Anthony Trudeau</dc:creator>
            <guid>http://geekswithblogs.net/tonyt/archive/2008/01/16/118612.aspx</guid>
            <pubDate>Wed, 16 Jan 2008 14:51:56 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/tonyt/comments/118612.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/tonyt/archive/2008/01/16/118612.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/tonyt/comments/commentRss/118612.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/tonyt/services/trackbacks/118612.aspx</trackback:ping>
        </item>
        <item>
            <title>Book review: Introducing Microsoft LINQ</title>
            <link>http://geekswithblogs.net/tonyt/archive/2008/01/08/118374.aspx</link>
            <description>&lt;p&gt;&lt;img height="130" alt="" width="130" border="0" src="http://www.microsoft.com/MSPress/books/imgt/10725.gif" /&gt; &lt;/p&gt;
&lt;p&gt;I got this book as a Christmas present and quickly read through it cover to cover.  The primary focus of the book is to provide an introduction to LINQ (language integrated query) that is available in the Microsoft .NET Framework 3.5.  In this end the book does a good job.  Just don't look for anything comprehensive.&lt;/p&gt;
&lt;p&gt;The book starts out talking about what LINQ is and follows that up with a few chapters that talk about the new language features in C# and VB that make LINQ possible.  I found the information to give me a good understanding about how LINQ works if only at a very high level.  However, these chapters take up about 20% of the book.  I feel the author would have been better off shortening these chapters and adding more meat to other sections.&lt;/p&gt;
&lt;p&gt;The syntax fundamentals follow the introduction.  The chapter starts out good, but seems to become a regurgitation of product documentation towards the end.  The fundamentals chapter is followed by chapters on the different flavors of LINQ that is LINQ to SQL, LINQ to Entities, etc.  The one part of the book that I felt was really lacking is the LINQ to Entities section which was given a whopping three pages.&lt;/p&gt;
&lt;p&gt;That all said, the book did a good job of getting me familiar with what the technology is and can do, and what options I have for using the technology in different areas.  The information is based on the beta, and although I didn't look for differences I didn't run into any either.  You could get the same information this book provides by reading the production documentation as well as several online articles on the subject of LINQ, but if you're like me you like it in one place in a convenient format to sit back and work through.&lt;/p&gt;
&lt;p&gt;The list price on the book is way out there, but Amazon has it for a much more reasonable price of $23.  I would recommend this book based on its ability to provide a good introduction keeping in mind that it doesn't offer advanced or in-depth coverage.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=118374"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=118374" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/tonyt/aggbug/118374.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Anthony Trudeau</dc:creator>
            <guid>http://geekswithblogs.net/tonyt/archive/2008/01/08/118374.aspx</guid>
            <pubDate>Tue, 08 Jan 2008 12:30:08 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/tonyt/comments/118374.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/tonyt/archive/2008/01/08/118374.aspx#feedback</comments>
            <slash:comments>3</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/tonyt/comments/commentRss/118374.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/tonyt/services/trackbacks/118374.aspx</trackback:ping>
        </item>
        <item>
            <title>Custom dictionary at the project level</title>
            <link>http://geekswithblogs.net/tonyt/archive/2007/12/26/117999.aspx</link>
            <description>&lt;p&gt;The MSDN documentation indicates that the custom dictionary for the naming rules in the Visual Studio code analysis can be applied at the project level.  I prefer a local scope for terms that don't have a scope global to all my projects (e.g. the company name is good to have global but a product name doesn't really need to be in the global dictionary).  Unfortunately, it doesn't tell you all the information you need to actually use the custom dictionary.&lt;/p&gt;
&lt;p&gt;The first thing to do is create the custom dictionary that you want to use for the project.  The MSDN documentation provides the file format for the file.  The easiest way to do this would be to click Add New Item from the Project menu.  Select XML file and change the name to CustomDictionary.xml and then copy the format from the MSDN documentation.  Next add your words and acronyms as needed.&lt;/p&gt;
&lt;p&gt;The final steps are all done from within Visual Studio and is where the MSDN documentation lets you down.  Select the file in the Solution Explorer and change its properties as follows:&lt;/p&gt;
&lt;p&gt;Build Action = CodeAnalysisDictionary&lt;br /&gt;
Copy to Output Directory = Do not copy&lt;/p&gt;
&lt;p&gt;These steps basically add the /dictionary switch to the build action for calling FxCopCmd.  I've added user content to the MSDN documentation online, but hopefully this article will help those that don't notice it.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=117999"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=117999" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/tonyt/aggbug/117999.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Anthony Trudeau</dc:creator>
            <guid>http://geekswithblogs.net/tonyt/archive/2007/12/26/117999.aspx</guid>
            <pubDate>Thu, 27 Dec 2007 00:58:14 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/tonyt/comments/117999.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/tonyt/archive/2007/12/26/117999.aspx#feedback</comments>
            <slash:comments>3</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/tonyt/comments/commentRss/117999.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/tonyt/services/trackbacks/117999.aspx</trackback:ping>
        </item>
        <item>
            <title>Example: Regular Expression Alternation</title>
            <link>http://geekswithblogs.net/tonyt/archive/2007/09/11/115283.aspx</link>
            <description>&lt;p&gt;So, the scenario is that you want to do some specific validation or matching, but part of what you're validating or matching will decide how the rest is validated or matched.  For example, in my scenario I have a field in the database that will store a report destination in the URI format that can be either for e-mail, FTP, or a file (mailto://, ftp://, or file://).  You could create three regular expressions and evaluate each, but that can be klunky especially if you're doing on the fly validation through a control like the Infragistics UltraWinGrid which allows you to set a regular expression as a validator on the column.&lt;/p&gt;
&lt;p&gt;Alternations for expressions are what you need.  Specifically, the .NET Framework specifies the following format for the alternation expression:&lt;/p&gt;
&lt;p&gt;&lt;font face="Arial"&gt;(?(expression)yes|no)&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;The easiest way to specify the expression is as a named group.  And then yes and no become the remaining patterns to match if the named group specified in the expression has a match.  Therefore, for my scenario I could write the shell of my regular expression as (ignore case option is set):&lt;/p&gt;
&lt;p&gt;^((?&amp;lt;isMail&amp;gt;mailto)|(?&amp;lt;isFtp&amp;gt;ftp)|(?&amp;lt;isFile&amp;gt;file)):\/\/(?(isMail)yes|(?(isFtp)yes|no))$&lt;/p&gt;
&lt;p&gt;This basically could be read as:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;Match the protocol as "mailto", "ftp", or "file" &lt;/li&gt;
    &lt;li&gt;If we matched the protocol as "mailto" then
    &lt;ul&gt;
        &lt;li&gt;Match the rest of the string as an e-mail address &lt;/li&gt;
    &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;Else if we matched the protocol as "ftp" then
    &lt;ul&gt;
        &lt;li&gt;Match the rest of the string as an FTP address &lt;/li&gt;
    &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;Else
    &lt;ul&gt;
        &lt;li&gt;Match the rest of the string as a file &lt;/li&gt;
    &lt;/ul&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;From this point, you need to determine the regular expressions to match the mail, FTP, and file format.  I used the following:&lt;/p&gt;
&lt;p&gt;e-mail: &lt;font face="Arial"&gt;([\w\-\.]+)@((\[([0-9]{1,3}\.){3}[0-9]{1,3}\])|(([\w\-]+\.)+)([a-zA-Z]{2,4}))&lt;br /&gt;
ftp: &lt;font face="Arial"&gt;(?:[\w.]+\/?)|(([A-Z]:\\[^/:\*\?&amp;lt;&amp;gt;\|]+\.\w{2,6})&lt;br /&gt;
file: (\&lt;font face="Arial"&gt;\{2}[^/:\*\?&amp;lt;&amp;gt;\|]+\.\w{2,6&lt;/font&gt;})&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;At this point, it's just a matter of putting the values into the format I came up with earlier and I have a single regular expression to match the URIs that I care about.&lt;/p&gt;
&lt;p&gt;&lt;font face="Arial"&gt;^((?&amp;lt;isMail&amp;gt;mailto)|(?&amp;lt;isFtp&amp;gt;ftp)|(?&amp;lt;isFile&amp;gt;file)):\/\/(?(isMail)([\w\-\.]+)@((\[([0-9]{1,3}\.){3}[0-9]{1,3}\])|(([\w\-]+\.)+)([a-zA-Z]{2,4}))|(?(isFtp)(?:[\w.]+\/?)|(([A-Z]:\\[^/:\*\?&amp;lt;&amp;gt;\|]+\.\w{2,6})|(\\{2}[^/:\*\?&amp;lt;&amp;gt;\|]+\.\w{2,6}))))$&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=115283"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=115283" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/tonyt/aggbug/115283.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Anthony Trudeau</dc:creator>
            <guid>http://geekswithblogs.net/tonyt/archive/2007/09/11/115283.aspx</guid>
            <pubDate>Tue, 11 Sep 2007 16:40:35 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/tonyt/comments/115283.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/tonyt/archive/2007/09/11/115283.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/tonyt/comments/commentRss/115283.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/tonyt/services/trackbacks/115283.aspx</trackback:ping>
        </item>
        <item>
            <title>Making your assemblies visible to Visual Studio</title>
            <link>http://geekswithblogs.net/tonyt/archive/2007/06/21/113365.aspx</link>
            <description>&lt;p&gt;So, you created your super cool library and you want to be able to use it within your application.  You maybe even installed it in the GAC.  But, it doesn't show up in the Add Reference dialog unless you browse to it.  What are you to do?&lt;/p&gt;
&lt;p&gt;There are two approaches:&lt;/p&gt;
&lt;ol&gt;
    &lt;li&gt;Copy the assemblies to the C:\Windows\Microsoft.NET\Framework\v2.0.50727 folder (version may vary) or the C:\Program Files\Microsoft Visual Studio8\Common7\IDE folder. &lt;/li&gt;
    &lt;li&gt;Add a special assembly folder key to the Registry &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Personally, I believe the latter option is the best option and seems to be the method that third party vendors use.  This method will cause Visual Studio to search the folder you specify in addition to the default folders.  Here's what you need to do:&lt;/p&gt;
&lt;ol&gt;
    &lt;li&gt;Browse to the HKLM\Software\Microsoft\.NETFramework\AssemblyFolders key &lt;/li&gt;
    &lt;li&gt;Add a new key with whatever name you want (keep in mind that you'll need a key for separate folders) &lt;/li&gt;
    &lt;li&gt;Set the default value of the key to the folder where the assemblies are installed &lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=113365"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=113365" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/tonyt/aggbug/113365.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Anthony Trudeau</dc:creator>
            <guid>http://geekswithblogs.net/tonyt/archive/2007/06/21/113365.aspx</guid>
            <pubDate>Thu, 21 Jun 2007 15:43:55 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/tonyt/comments/113365.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/tonyt/archive/2007/06/21/113365.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/tonyt/comments/commentRss/113365.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/tonyt/services/trackbacks/113365.aspx</trackback:ping>
        </item>
        <item>
            <title>Exposing a collection in your object model</title>
            <link>http://geekswithblogs.net/tonyt/archive/2007/06/18/113301.aspx</link>
            <description>&lt;p&gt;Sometimes it's necessary to expose an internal collection from an object to a hosting object.  However, usually your object wants to control the changes to the collection.  You can easily pass an array to the hosting object using the ToArray method, but that array is static to the hosting object.  What if the hosting object needs updates?&lt;/p&gt;
&lt;p&gt;The best way to illustrate the problem is with an example.  In this example, I have a simple Windows Forms project with a Form that has an Infragistics UltraWinGrid (although any data grid will work that supports binding to an IList).  I prefer not to expose internal controls to objects such as presenters in an MVP pattern, so that means my data which is not based on a database needs to be stored in another class or within the Form class, and I certainly don't like the latter option.&lt;/p&gt;
&lt;p&gt;It just so happens that my object which I'll call a manager is responsible for the collection and for performing work based on the contents of the collection.  The work being done is irrelevant for this article, but if you're curious I am spawning a separate thread which contacts a legacy application via TCP and submits jobs/requests for printing (after they've been processed through a workflow).  The manager exposes some modification methods such as AddRequest, CancelRequest, et al.  And those methods are the only way I want the outside world to modify the collection.  But, at the same time the data grid needs to have access to the current data without needing to requery the property.&lt;/p&gt;
&lt;p&gt;Enter the AsReadyOnly method.  This method exposed by the List&amp;lt;T&amp;gt;, Set&amp;lt;T&amp;gt;, Array, and others generates what is basically an adapter to your collection.  The return value is a System.Collections.ObjectModel.ReadOnlyCollection&amp;lt;T&amp;gt; that is the best of both worlds -- it shows live data from the internal collection and it doesn't let the consumer modify the collection contents.&lt;/p&gt;
&lt;p&gt;Here's an example of the implementation&lt;/p&gt;
&lt;p&gt;public class MyManagerClass&lt;br /&gt;
{&lt;br /&gt;
     private List&amp;lt;MyObject&amp;gt; _objects = new List&amp;lt;MyObject&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
     public ReadOnlyCollection&amp;lt;MyObject&amp;gt; Objects&lt;br /&gt;
     {&lt;br /&gt;
          get { return _objects.AsReadOnly(); }&lt;br /&gt;
     }&lt;br /&gt;
}&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=113301"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=113301" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/tonyt/aggbug/113301.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Anthony Trudeau</dc:creator>
            <guid>http://geekswithblogs.net/tonyt/archive/2007/06/18/113301.aspx</guid>
            <pubDate>Mon, 18 Jun 2007 21:15:28 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/tonyt/comments/113301.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/tonyt/archive/2007/06/18/113301.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/tonyt/comments/commentRss/113301.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/tonyt/services/trackbacks/113301.aspx</trackback:ping>
        </item>
    </channel>
</rss>