<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;CEUNSXgyeip7ImA9WhRUFUQ.&quot;"><id>tag:blogger.com,1999:blog-7297021906893122222</id><updated>2012-01-26T10:38:18.692-05:00</updated><category term="Personal" /><category term="Rx" /><category term="Threading" /><category term="Language design" /><category term="jQuery" /><category term="Option Parsing" /><category term="xmldoc" /><category term="Certification" /><category term="MVVM/WPF" /><category term="dynamic" /><category term="IT" /><category term="Code Contracts" /><category term="OpenSSL" /><category term="IDisposable/Finalizers" /><category term="Nito.KitchenSink" /><category term="Sharp Corners" /><category term="Windows Services" /><category term="Nito.AsyncEx" /><category term="Windows" /><category term="MSBuild" /><category term="Firmware" /><category term="Programming" /><category term="Sample code" /><category term="Device drivers" /><category term="ASP.NET" /><category term="PDBs" /><category term="Oops" /><category term="Simple and Easy" /><category term="NuGet" /><category term="P/Invoke" /><category term="Lighter Notes" /><category term="TCP/IP sockets" /><category term="Linq" /><category term="WiX" /><category term="Nito.Async" /><category term="async" /><category term="MSbug" /><category term="callbacks" /><category term="Silverlight" /><category term=".NET" /><category term="Books" /><title>Nito Programming</title><subtitle type="html">public Task&amp;lt;object&amp;gt; WordOfGod(); // Is 55:11</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://nitoprograms.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://nitoprograms.blogspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Stephen Cleary, Nito Programs</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>160</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/blogspot/OlZtT" /><feedburner:info uri="blogspot/olztt" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;Ak8MR30yeSp7ImA9WhRRF0w.&quot;"><id>tag:blogger.com,1999:blog-7297021906893122222.post-3092811678661560282</id><published>2011-12-01T00:46:00.001-05:00</published><updated>2011-12-01T00:54:46.391-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-01T00:54:46.391-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Personal" /><title>Out for a Bit</title><content type="html">&lt;p&gt;There are several things that I was planning to do over the last week or two:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Collect my slides, notes, and demos for my "Thread is Dead" talk recently given at GRDevDay.&lt;/li&gt;
&lt;li&gt;Update Nito.AsyncEx to support Silverlight 5 and possibly also Windows Phone.&lt;/li&gt;
&lt;li&gt;Finish my "command line parsing" series of blog posts, and start a new series looking at "async in the real world" - essentially my "Thread is Dead" talk broken up into a couple dozen posts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unfortunately, sometimes the unexpected happens. My two-year-old son &lt;a href="http://sdcleary.blogspot.com/"&gt;has been diagnosed&lt;/a&gt; with Leukemia, and I am writing this far from home in his hospital room.&lt;/p&gt;

&lt;p&gt;I do still plan to do all of the things listed above, but they won't get done as soon as I was hoping. My apologies especially to the GRDevDay people!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7297021906893122222-3092811678661560282?l=nitoprograms.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OlZtT/~4/BL3-I9YJIfo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://nitoprograms.blogspot.com/feeds/3092811678661560282/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://nitoprograms.blogspot.com/2011/12/out-for-bit.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/3092811678661560282?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/3092811678661560282?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OlZtT/~3/BL3-I9YJIfo/out-for-bit.html" title="Out for a Bit" /><author><name>Stephen Cleary</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total><feedburner:origLink>http://nitoprograms.blogspot.com/2011/12/out-for-bit.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkcHQHY4cCp7ImA9WhRRE0g.&quot;"><id>tag:blogger.com,1999:blog-7297021906893122222.post-4708674097342024260</id><published>2011-11-26T15:28:00.000-05:00</published><updated>2011-11-26T18:27:11.838-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-11-26T18:27:11.838-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="IT" /><title>Virtualizing Two Machines over Thanksgiving</title><content type="html">&lt;p&gt;Like many "computer people," I do a lot of admin work for friends and familiy. Over the last few years, I've worked with &lt;a href="http://landmarkbaptist.com"&gt;my church&lt;/a&gt; to get them out of the dark ages of computing. The process is almost complete; I only have one more machine to replace, and then they will all be 64-bit dual-core 4GB systems running Pro editions of Windows. Next year I hope to (finally) put in a domain.&lt;/p&gt;

&lt;p&gt;It turns out that two of the old machines have some outdated software that's critical to weekly operations. I'm working on replacements for the software, but in the meantime, the old machines were just sitting around, taking up space in the church office.&lt;/p&gt;

&lt;p&gt;I decided to try to virtualize these machines on Friday (the day after Thanksgiving). This blog entry is just a "lessons learned" from this adventure.&lt;/p&gt;

&lt;h4&gt;The Challenge, and the Plan&lt;/h4&gt;

&lt;p&gt;The old "server" (XP Home with 192 MB RAM) and the old office machine (XP Home with 256 MB RAM) both needed virtualization. Due to the way the weekly process is done in the office, the old server would have to be virtualized onto the new server, and the old office machine would have to be virtualized onto the new office machine.&lt;/p&gt;

&lt;p&gt;I'm most familiar with &lt;a href="http://www.vmware.com/"&gt;VMWare products&lt;/a&gt; (particularly VMWare Workstation), and I highly recommend them. However, I wanted to see if it was possible to virtualize these machines without incurring a licensing cost. My budget at Landmark Baptist isn't comparable to most IT departments. ;)  So, I decided to try Hyper-V or Virtual PC, falling back on VirtualBox if necessary (it wasn't).&lt;/p&gt;

&lt;p&gt;The server was the first machine to be replaced, so unfortunately at this point the new server has the most outdated hardware/OS. It's running Server 2008 but without Hyper-V... or even CPU virtualization support. :(  Furthermore, according to what I've read, Hyper-V doesn't support USB, which IMO is a significant limitation (and a showstopper for the old "server").&lt;/p&gt;

&lt;p&gt;So, I decided to try using Virtual PC for both virtual machines. The new office machine runs Win7 Pro, which is fully supported by the current version of Virtual PC ("Windows Virtual PC"). I was a bit apprehensive about the new server; Server 2008 isn't an officially supported platform for the previous version of Virtual PC ("Microsoft Virtual PC 2007 SP1"), but it turned out to work fine. Microsoft still has Virtual PC 2007 available for download, and SP1 added support for machines without virtualization hardware (which is just what I needed).&lt;/p&gt;

&lt;p&gt;One limitation with Virtual PC is that it can only handle 127 GB hard drives. In my case, both machines had hard drives much smaller than that, so it wasn't a problem.&lt;/p&gt;

&lt;p&gt;The plan at this point was to virtualize each machine to a different version of Virtual PC (running on different OSes and hardware). We'll see how well this worked in a moment, but first I'll mention the tool which kicked off this whole adventure.&lt;/p&gt;

&lt;p&gt;Systems Internals has a great tool called &lt;a href="http://technet.microsoft.com/en-us/sysinternals/ee656415"&gt;disk2vhd&lt;/a&gt;, which can create a virtual disk from a physical disk - even storing the virtual disk image on the physical disk it's imaging, while the physical disk is running the OS running disk2vhd. If you think about it, that's pretty cool.&lt;/p&gt;

&lt;p&gt;Disk2vhd can take quite a while (i.e., 8-10 hours) to run, so I tried to make my plan where it would run overnight. Once I have the machines in a VHD image, I should be able to create a Virtual PC machine using that for a hard drive. VirtualBox also supports VHD, so my fallback would be ready just in case.&lt;/p&gt;

&lt;p&gt;There are several articles on the Internet where others have successfully converted a physical XP machine to a virtual PC on Windows 7. The steps are straightforward: Create a disk image using disk2vhd; copy the image to the host PC; set up a new virtual machine in Virtual PC; re-activate Windows on the virtual machine; and install Integration Components/Services.&lt;/p&gt;

&lt;p&gt;One final note: during my preparations, I discovered that XP can run into a stop 0x7B when backing up to a disk image and restoring on different hardware (which is very similar to what I'm doing with disk2vhd). The steps to fix this are in &lt;a href="http://support.microsoft.com/kb/314082"&gt;KB314082&lt;/a&gt;. I did not run into this issue, but I'm including it here for others who may.&lt;/p&gt;

&lt;p&gt;On Wednesday (the day before Thanksgiving), I had done all the research and established my plan. I downloaded disk2vhd, VirtualBox, and both versions of Virtual PC onto my USB drive and left for Petoskey. That night, I started both machines running disk2vhd and went over to my Mom's for Thanksgiving.&lt;/p&gt;

&lt;h4&gt;A Snag: OEM OS&lt;/h4&gt;

&lt;p&gt;I popped in to check the status on Thursday morning. The server disk2vhd failed; my external USB drive had a faulty power adapter and it had shorted out overnight. So I restarted it with my other USB drive, and turned my attention to the office machine.&lt;/p&gt;

&lt;p&gt;I had noticed on the disk2vhd download page that OEM OS licenses prevent virtualization. Turns out the office machine was XP Home OEM. The VHD came out fine, but it was not possible to re-activate Windows on the virtual machine. I did have a spare XP Home Retail key, but apparently you can't activate an OEM install with a Retail key. I also tried the original OEM key, but that didn't work since it's keyed to the BIOS which is different in a virtual machine.&lt;/p&gt;

&lt;p&gt;Re-installing the OS was out of the question (if I actually &lt;i&gt;had&lt;/i&gt; the install media for the outdated programs, I would have installed them on the new machine and we wouldn't need to virtualize in the first place). In desperation, I searched online for any way to convert OEM to Retail in-place. Most of the articles recommended running a repair from a different CD, but that seemed hokey to me (how would that affect updates already installed?).&lt;/p&gt;

&lt;p&gt;Finally, I discovered the &lt;a href="http://go.microsoft.com/fwlink/?LinkId=204141"&gt;Product Key Update Tool&lt;/a&gt;. I ran it on the old office machine, converting it from OEM to Retail, and then re-started disk2vhd. This time, I ran disk2vhd with the output disk image going directly over the network to the new host PC; this worked just fine and I highly recommend it.&lt;/p&gt;

&lt;p&gt;During my searching, I also discovered &lt;b&gt;sysprep&lt;/b&gt;. The Product Key Update Tool changes the old key to a new key; whereas Sysprep removes the existing key, requiring the user to type it in the next time the computer boots. I used the Update Tool, but Sysprep would probably also work.&lt;/p&gt;

&lt;h4&gt;Another Snag: Remote Control&lt;/h4&gt;

&lt;p&gt;I was hoping to do most of the work on Friday from the comfort of my Mom's living room, eating Thanksgiving leftovers and watching the kids play with their uncles. Unfortunately, I could not get mouse capture to work at all remotely before Integration Services were installed.&lt;/p&gt;

&lt;p&gt;It doesn't appear to be possible to set up a new virtual machine remotely. At least not using &lt;a href="https://secure.logmein.com/"&gt;LogMeIn&lt;/a&gt;, which is my remote control software of choice; in the past I've used pcAnywhere, UltraVNC, and Windows Live Mesh, but I've now settled solidly on LogMeIn.&lt;/p&gt;

&lt;p&gt;I also tried to LogMeIn into another computer and Remote Desktop to the Virtual PC host; however, the mouse capture was still funky (the scale was messed up). Once I got Integration Services installed, remotely controlling a host PC worked fine.&lt;/p&gt;

&lt;p&gt;So, I ended up having to physically be present for the initial virtual machine setup, which was disappointing.&lt;/p&gt;

&lt;h4&gt;Another Snag: Networking&lt;/h4&gt;

&lt;p&gt;When I brought up the old "server" as a virtual machine on the new server, the networking didn't work. Since I only had the Windows Activation UI available, it wasn't possible to diagnose. By default, Virtual PC will share the host's network card (using a network switch in software). The new server had a static IP, but this shouldn't have caused a problem. When I switched it to use NAT (a network router in software), the problem went away.&lt;/p&gt;

&lt;p&gt;I've always used NAT for my VMWare virtual machines, so this was a natural step.&lt;/p&gt;

&lt;h4&gt;Issue: Slow Initial Boot&lt;/h4&gt;

&lt;p&gt;The "server" disk2vhd process never finished. I'm not entirely sure why; the disk file was approximately the correct size, but disk2vhd never completed. Eventually I just exited the program and decided to try to use the file anyway.&lt;/p&gt;

&lt;p&gt;When starting the old server as a virtual machine for the first time, it took about an hour to get from initial startup, through Windows activation, and to the desktop. Virtual PC was pegging the CPU the entire time. I'm unsure of the reason for this; the host PC does not have virtualization hardware, the vhd could be incomplete, the vhd is dynamic, ...&lt;/p&gt;

&lt;p&gt;Once I installed Integration Components and rebooted, the CPU problems disappeared. I can't say whether the resolution was due to the installation or the rebooting.&lt;/p&gt;

&lt;h4&gt;Issue: Integration Components on XP Home&lt;/h4&gt;

&lt;p&gt;The virtualized XP office machine is running on Windows Virtual PC under a Windows 7 Pro host. Normally, this situation allows a really neat trick: you can set up a program on the virtual machine so it looks like a program on the host, with its own Start menu entry, running in a regular window instead of a full virtual machine desktop, etc.&lt;/p&gt;

&lt;p&gt;Unfortunately, that does not work if the virtual machine is XP Home. Apparently, the Integration Components use RDP (Remote Desktop) for that functionality. The auto-login feature is also not available.&lt;/p&gt;

&lt;h4&gt;Conclusion&lt;/h4&gt;

&lt;p&gt;The project was completed, though it took longer than I expected. I'll find out next week if everything works sufficiently on the virtualized machines.&lt;/p&gt;

&lt;p&gt;Lessons learned:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You cannot virtualize an OEM install. You have to change it to a Retail install first, using the &lt;a href="http://go.microsoft.com/fwlink/?LinkId=204141"&gt;Product Key Update Tool&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://technet.microsoft.com/en-us/sysinternals/ee656415"&gt;Disk2vhd&lt;/a&gt; can target a vhd image over the network.&lt;/li&gt;
&lt;li&gt;You must be physically present to set up the virtual machines, at least until the point that Integration Services are installed.&lt;/li&gt;
&lt;li&gt;If you're having problems getting the virtual machine on the network, try using NAT.&lt;/li&gt;
&lt;li&gt;Some Integration Components features do not work if the guest is XP Home.&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7297021906893122222-4708674097342024260?l=nitoprograms.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OlZtT/~4/pTCfE9z4_Qc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://nitoprograms.blogspot.com/feeds/4708674097342024260/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://nitoprograms.blogspot.com/2011/11/virtualizing-two-machines-over.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/4708674097342024260?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/4708674097342024260?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OlZtT/~3/pTCfE9z4_Qc/virtualizing-two-machines-over.html" title="Virtualizing Two Machines over Thanksgiving" /><author><name>Stephen Cleary</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://nitoprograms.blogspot.com/2011/11/virtualizing-two-machines-over.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CU8MRHkyeCp7ImA9WhdbFk0.&quot;"><id>tag:blogger.com,1999:blog-7297021906893122222.post-3253379317202462495</id><published>2011-10-13T12:30:00.000-04:00</published><updated>2011-10-14T10:51:25.790-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-14T10:51:25.790-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Option Parsing" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="Nito.KitchenSink" /><title>Option Parsing: Case Sensitivity</title><content type="html">&lt;p&gt;By default, all option parsing is case-sensitive:&lt;/p&gt;

&lt;pre class="brush:csharp"&gt;
class Program
{
  private sealed class Options : OptionArgumentsBase
  {
    [Option(&amp;quot;name&amp;quot;, 'n')]
    public string Name { get; private set; }
  }

  static int Main(string[] args)
  {
    try
    {
      var options = OptionParser.Parse&amp;lt;Options&amp;gt;();
      Console.WriteLine(&amp;quot;Name: &amp;quot; + options.Name);
      return 0;
    }
    catch (OptionParsingException ex)
    {
      Console.Error.WriteLine(ex.Message);
      return 2;
    }
    catch (Exception ex)
    {
      Console.Error.WriteLine(ex);
      return 1;
    }
  }
}
&lt;/pre&gt;

&lt;pre&gt;
&amp;gt; CommandLineParsingTest.exe /name Bob
Name: Bob

&amp;gt; CommandLineParsingTest.exe /Name Bob
Unknown option  Name  in parameter  /Name
&lt;/pre&gt;

&lt;p&gt;This is normal for Unix users, but Windows users expect case-insensitivity. You can pass your own &lt;b&gt;StringComparer&lt;/b&gt; to the &lt;b&gt;Parse&lt;/b&gt; method to support case-insensitivity:&lt;/p&gt;

&lt;pre class="brush:csharp"&gt;
class Program
{
  private sealed class Options : OptionArgumentsBase
  {
    [Option(&amp;quot;name&amp;quot;, 'n')]
    public string Name { get; private set; }
  }

  static int Main(string[] args)
  {
    try
    {
      var options = OptionParser.Parse&amp;lt;Options&amp;gt;(stringComparer:StringComparer.CurrentCultureIgnoreCase);
      Console.WriteLine(&amp;quot;Name: &amp;quot; + options.Name);
      return 0;
    }
    catch (OptionParsingException ex)
    {
      Console.Error.WriteLine(ex.Message);
      return 2;
    }
    catch (Exception ex)
    {
      Console.Error.WriteLine(ex);
      return 1;
    }
  }
}
&lt;/pre&gt;

&lt;pre&gt;
&amp;gt; CommandLineParsingTest.exe /name Bob
Name: Bob

&amp;gt; CommandLineParsingTest.exe /Name Bob
Name: Bob
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7297021906893122222-3253379317202462495?l=nitoprograms.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OlZtT/~4/_QYAtMGz6m4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://nitoprograms.blogspot.com/feeds/3253379317202462495/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://nitoprograms.blogspot.com/2011/10/option-parsing-case-sensitivity.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/3253379317202462495?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/3253379317202462495?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OlZtT/~3/_QYAtMGz6m4/option-parsing-case-sensitivity.html" title="Option Parsing: Case Sensitivity" /><author><name>Stephen Cleary</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://nitoprograms.blogspot.com/2011/10/option-parsing-case-sensitivity.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkQARH0_eCp7ImA9WhdbEEw.&quot;"><id>tag:blogger.com,1999:blog-7297021906893122222.post-4272680031731395365</id><published>2011-10-06T12:30:00.000-04:00</published><updated>2011-10-07T13:59:05.340-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-07T13:59:05.340-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Option Parsing" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="Nito.KitchenSink" /><title>Option Parsing; Positional Arguments</title><content type="html">&lt;p&gt;"Positional arguments" are any arguments not associated with an option. When using the &lt;a href="http://nuget.org/List/Packages/Nito.KitchenSink.OptionParsing"&gt;Nito.KitchenSink option parsing library&lt;/a&gt;, positional arguments must come after any options and their arguments.&lt;/p&gt;

&lt;h4&gt;Individual Positional Arguments&lt;/h4&gt;

&lt;p&gt;You can use the &lt;b&gt;PositionalArgumentAttribute&lt;/b&gt; to specify positional arguments in your options class. This attribute takes a single integral parameter, the 0-based index of the positional argument.&lt;/p&gt;

&lt;p&gt;Positional arguments support the entire range of &lt;a href="http://nitoprograms.blogspot.com/2011/08/option-parsing-argument-parsing.html"&gt;parsing possibilities&lt;/a&gt;, including &lt;b&gt;SimpleParserAttribute&lt;/b&gt;.&lt;/p&gt;

&lt;p&gt;This example uses a regular &lt;b&gt;Level&lt;/b&gt; option along with a &lt;b&gt;Name&lt;/b&gt; positional parameter.&lt;/p&gt;

&lt;pre class="brush:csharp"&gt;
class Program
{
  private sealed class Options : OptionArgumentsBase
  {
    [Option('l')]
    public int? Level { get; set; }

    [PositionalArgument(0)]
    public string Name { get; set; }
  }

  static int Main()
  {
    try
    {
      var options = OptionParser.Parse&amp;lt;Options&amp;gt;();

      Console.WriteLine(&amp;quot;Level: &amp;quot; + options.Level);
      Console.WriteLine(&amp;quot;Name: &amp;quot; + options.Name);

      return 0;
    }
    catch (OptionParsingException ex)
    {
      Console.Error.WriteLine(ex.Message);
      return 2;
    }
    catch (Exception ex)
    {
      Console.Error.WriteLine(ex);
      return 1;
    }
  }
}
&lt;/pre&gt;

&lt;pre&gt;
&amp;gt; CommandLineParsingTest.exe
Level:
Name:

&amp;gt; CommandLineParsingTest.exe Bob
Level:
Name: Bob

&amp;gt; CommandLineParsingTest.exe -l 13
Level: 13
Name:

&amp;gt; CommandLineParsingTest.exe -l 13 Bob
Level: 13
Name: Bob

&amp;gt; CommandLineParsingTest.exe Bob -l 13
Unknown parameter  -l
&lt;/pre&gt;

&lt;p&gt;The last test above shows that positional arguments must come after all regular options.&lt;/p&gt;

&lt;p&gt;If you need to pass a positional argument that starts with a dash (-) or forward slash (/), you can pass the special option "--", which forces all remaining command-line arguments to be interpreted as positional arguments:&lt;/p&gt;

&lt;pre&gt;
&amp;gt; CommandLineParsingTest.exe -Negative
Unknown option  N  in parameter  -Negative

&amp;gt; CommandLineParsingTest.exe -- -Negative
Level:
Name: -Negative
&lt;/pre&gt;

&lt;h4&gt;The Positional Argument Collection&lt;/h4&gt;

&lt;p&gt;Every options class must have one property that can receive "extra" positional arguments. Extra positional arguments are any positional arguments after those defined by &lt;b&gt;PositionalArgumentAttribute&lt;/b&gt;.&lt;/p&gt;

&lt;p&gt;Most programs do not need this functionality, so the &lt;b&gt;OptionArgumentsBase&lt;/b&gt; class provides a simple collection called &lt;b&gt;AdditionalArguments&lt;/b&gt;. By default, &lt;b&gt;OptionArgumentsBase.Validate&lt;/b&gt; will throw an &lt;b&gt;UnknownOptionException&lt;/b&gt; if any positional arguments end up in that collection.&lt;/p&gt;

&lt;p&gt;A program may make use of the &lt;b&gt;AdditionalArguments&lt;/b&gt; collection by overriding &lt;b&gt;Validate&lt;/b&gt;:&lt;/p&gt;

&lt;pre class="brush:csharp"&gt;
class Program
{
  private sealed class Options : OptionArgumentsBase
  {
    [PositionalArgument(0)]
    public string Name { get; set; }

    public override void Validate()
    {
    }
  }

  static int Main()
  {
    try
    {
      var options = OptionParser.Parse&amp;lt;Options&amp;gt;();

      Console.WriteLine(&amp;quot;Name: &amp;quot; + options.Name);
      Console.WriteLine(&amp;quot;ArgList: &amp;quot; + string.Join(&amp;quot;, &amp;quot;, options.AdditionalArguments));

      return 0;
    }
    catch (OptionParsingException ex)
    {
      Console.Error.WriteLine(ex.Message);
      return 2;
    }
    catch (Exception ex)
    {
      Console.Error.WriteLine(ex);
      return 1;
    }
  }
}
&lt;/pre&gt;

&lt;pre&gt;
&amp;gt; CommandLineParsingTest.exe
Name:
ArgList:

&amp;gt; CommandLineParsingTest.exe Bob
Name: Bob
ArgList:

&amp;gt; CommandLineParsingTest.exe Bob 17
Name: Bob
ArgList: 17

&amp;gt; CommandLineParsingTest.exe Bob -l 13
Name: Bob
ArgList: -l, 13

&amp;gt; CommandLineParsingTest.exe -- Bob
Name: Bob
ArgList:
&lt;/pre&gt;

&lt;p&gt;Alternatively, an options class may provide its own collection, marked with the &lt;b&gt;PositionalArgumentsAttribute&lt;/b&gt; (note the plural "Argument&lt;b&gt;s&lt;/b&gt;"). When it does this, the options class may &lt;i&gt;not&lt;/i&gt; derive from &lt;b&gt;OptionArgumentsBase&lt;/b&gt;; rather, it should implement the &lt;b&gt;IOptionArguments&lt;/b&gt; interface.&lt;/p&gt;

&lt;p&gt;The property does not have to be &lt;b&gt;List&amp;lt;string&amp;gt;&lt;/b&gt; (which is used by &lt;b&gt;OptionArgumentsBase&lt;/b&gt;). The only requirements on the collection is that it only have one method named &lt;b&gt;Add&lt;/b&gt; which takes a single parameter. The parameter does not have to be &lt;b&gt;string&lt;/b&gt;; it can be any type, and the &lt;a href="http://nitoprograms.blogspot.com/2011/08/option-parsing-argument-parsing.html"&gt;standard parsing rules&lt;/a&gt; apply.&lt;/p&gt;

&lt;blockquote&gt;This means that &lt;b&gt;PositionalArguments&lt;/b&gt; can be placed on a property of dictionary type, as long as a matching parser is provided.&lt;/blockquote&gt;

&lt;p&gt;Here's an example of a program taking any number of integer parameters:&lt;/p&gt;

&lt;pre class="brush:csharp"&gt;
class Program
{
  private sealed class Options : IOptionArguments
  {
    public Options()
    {
      this.Integers = new List&amp;lt;int&amp;gt;();
    }

    [PositionalArguments]
    public List&amp;lt;int&amp;gt; Integers { get; private set; }

    public void Validate()
    {
    }
  }

  static int Main()
  {
    try
    {
      var options = OptionParser.Parse&amp;lt;Options&amp;gt;();

      Console.WriteLine(&amp;quot;Integers: &amp;quot; + string.Join(&amp;quot;, &amp;quot;, options.Integers));

      return 0;
    }
    catch (OptionParsingException ex)
    {
      Console.Error.WriteLine(ex.Message);
      return 2;
    }
    catch (Exception ex)
    {
      Console.Error.WriteLine(ex);
      return 1;
    }
  }
}
&lt;/pre&gt;

&lt;pre&gt;
&amp;gt; CommandLineParsingTest.exe
Integers:

&amp;gt; CommandLineParsingTest.exe 13
Integers: 13

&amp;gt; CommandLineParsingTest.exe 13 7
Integers: 13, 7

&amp;gt; CommandLineParsingTest.exe 13 7 Bob
Could not parse  Bob  as Int32
&lt;/pre&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7297021906893122222-4272680031731395365?l=nitoprograms.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OlZtT/~4/WI-c4mMhN0E" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://nitoprograms.blogspot.com/feeds/4272680031731395365/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://nitoprograms.blogspot.com/2011/10/option-parsing-positional-arguments.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/4272680031731395365?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/4272680031731395365?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OlZtT/~3/WI-c4mMhN0E/option-parsing-positional-arguments.html" title="Option Parsing; Positional Arguments" /><author><name>Stephen Cleary</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://nitoprograms.blogspot.com/2011/10/option-parsing-positional-arguments.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkcGQn07eip7ImA9WhdVEUo.&quot;"><id>tag:blogger.com,1999:blog-7297021906893122222.post-5502317969145444650</id><published>2011-09-16T09:00:00.000-04:00</published><updated>2011-09-16T09:00:23.302-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-16T09:00:23.302-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Rx" /><category scheme="http://www.blogger.com/atom/ns#" term="async" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><title>Rx and Async</title><content type="html">&lt;p&gt;I saw some rather shocking tweets yesterday from the BUILD conference:&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;img border="0" height="132" width="348" src="http://4.bp.blogspot.com/-pGyY6tjvz7o/TnNG8fH56qI/AAAAAAAAFv8/j0nAv_Orhb4/s1600/AndersNoRx.PNG" /&gt;&lt;br /&gt;
&lt;/div&gt;&lt;p&gt;The author of that original tweet followed up with &lt;a href=""&gt;a blog post&lt;/a&gt; with some interesting Rx-related quotes from Anders Hejlsberg: "I don't know if we've decided [whether Rx will be included in future versions of .NET]." and "Personally I've found the stuff we've done with async &lt;b&gt;allows you to do a lot more&lt;/b&gt; [than Rx]." (emphasis mine).&lt;/p&gt;&lt;p&gt;Interesting. I tried to take a listen for myself, but the Channel9 live interview was no longer available. Note that these remarks were made during a live interview, and were not part of a presentation; I'm hoping that Anders just answered off the cuff and didn't mean it.&lt;/p&gt;&lt;p&gt;One reason I found those quotes controversial is because parallel programming (TPL/PLINQ), background operations (async/await), and asynchronous streams (Rx) all address different problems. In particular, Async &lt;i&gt;only&lt;/i&gt; supports background operations and does &lt;i&gt;not&lt;/i&gt; support asynchronous streams. Rx supports both, but Async will become the default solution for background operations because it's easier to use than Rx.&lt;/p&gt;&lt;p&gt;So, I agree with Anders that Async is easier to use, but I totally disagree that Async is more powerful. Rx can do everything Async can do, and can do some things that Async &lt;i&gt;can't&lt;/i&gt; do.&lt;/p&gt;&lt;p&gt;It comes down to the difference between &lt;i&gt;asynchronous operations&lt;/i&gt; and &lt;i&gt;asynchronous events&lt;/i&gt;. An asynchronous operation is something that my program can start, and it will complete some time later. An asynchronous event stream is something that is happening all the time independent of my program; it can subscribe and unsubscribe, but does not &lt;i&gt;cause&lt;/i&gt; the events. This is an important distinction if you consider an event stream that produces in quick bursts (e.g., mouse movement); Rx allows collating all of those events, but an async-based solution may miss some (because it has to restart the operation each time it completes).&lt;/p&gt;&lt;p&gt;Historically, asynchronous &lt;i&gt;events&lt;/i&gt; have been a blind spot for Microsoft. Consider a condensed history of asynchronous support:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;b&gt;Asynchronous Programming Model (APM)&lt;/b&gt;. In the beginning, there was only IAsyncResult (Begin/End). The APM was everywhere, even baked into delegate types. The thing to note about APM is that it is purely an asynchronous operation; no asynchronous events are supported. The program starts the operation, which has a single point of completion.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Event-Based Asynchronous Pattern (EAP)&lt;/b&gt;. Way back in .NET 2.0, the EAP was introduced. EAP works by capturing the current SynchronizationContext and then raising events on that context. This was the first asynchronous pattern that supported both asynchronous operations and asynchronous events. Unfortunately, the documentation &lt;i&gt;assumed&lt;/i&gt; that EAP objects are only implementing asynchronous operations, and completely ignored the EAP support for asynchronous events. In addition, the most famous EAP implementation (BackgroundWorker) was just an asynchronous operation. However, the &lt;a href="nitoasync.codeplex.com"&gt;Nito.Async&lt;/a&gt; library included some helpers for EAP components, and included sample socket components using EAP in an asynchronous event fashion.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Rx&lt;/b&gt;. Supporting .NET 3.5 and up, the Rx libraries are all about asynchronous events (and they also support asynchronous operations, which are just a singleton asynchronous event). Rx is also more powerful than EAP because it has a very flexible execution context, while EAP ties everything through a single SynchronizationContext. However, the learning curve for Rx is steep.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Async/await and the Task-Based Asynchronous Pattern (TAP)&lt;/b&gt;. These extensions to the language allow for a very natural and easy way to deal with asynchronous operations, but they do not support asynchronous events.&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;In terms of &lt;i&gt;power&lt;/i&gt; and &lt;i&gt;flexibility&lt;/i&gt;, TAP is approximately equivalent to APM (less powerful than EAP and Rx). The only reason it's a step &lt;i&gt;forward&lt;/i&gt; is because it is so easy to learn and use. Some simple programs may use only TAP, but other programs will need both TAP and Rx.&lt;/p&gt;&lt;p&gt;Rx is a very welcome (and necessary) addition to our toolset. Async does not and can not replace it.&lt;/p&gt;&lt;p&gt;(P.S. All of this - and much more - is covered in my "Thread is Dead" talk, which has been submitted for consideration at a couple of conferences in the next few months. I'll update this space when it's accepted.)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7297021906893122222-5502317969145444650?l=nitoprograms.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OlZtT/~4/ueYiORlajjQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://nitoprograms.blogspot.com/feeds/5502317969145444650/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://nitoprograms.blogspot.com/2011/09/rx-and-async.html#comment-form" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/5502317969145444650?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/5502317969145444650?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OlZtT/~3/ueYiORlajjQ/rx-and-async.html" title="Rx and Async" /><author><name>Stephen Cleary</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-pGyY6tjvz7o/TnNG8fH56qI/AAAAAAAAFv8/j0nAv_Orhb4/s72-c/AndersNoRx.PNG" height="72" width="72" /><thr:total>5</thr:total><feedburner:origLink>http://nitoprograms.blogspot.com/2011/09/rx-and-async.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEUDRng7eyp7ImA9WhdWFUo.&quot;"><id>tag:blogger.com,1999:blog-7297021906893122222.post-2369806483622982104</id><published>2011-09-09T08:43:00.001-04:00</published><updated>2011-09-09T08:44:37.603-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-09T08:44:37.603-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="async" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="Nito.AsyncEx" /><category scheme="http://www.blogger.com/atom/ns#" term="Nito.Async" /><title>Nito.AsyncEx Available</title><content type="html">&lt;p&gt;Nito.AsyncEx is &lt;a href="http://nitoasyncex.codeplex.com/"&gt;now available&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Just as the &lt;a href="http://nitoasync.codeplex.com/"&gt;Nito.Async&lt;/a&gt; library helps you work with the Event-Based Asynchronous Pattern (and its underlying concepts such as SynchronizationContext), the &lt;a href="http://nitoasyncex.codeplex.com/"&gt;Nito.AsyncEx&lt;/a&gt; library helps you work with the Task-Based Asynchronous Pattern (and its underlying concepts such as Task).&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7297021906893122222-2369806483622982104?l=nitoprograms.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OlZtT/~4/i9P6CHWUzCU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://nitoprograms.blogspot.com/feeds/2369806483622982104/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://nitoprograms.blogspot.com/2011/09/nitoasyncex-available.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/2369806483622982104?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/2369806483622982104?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OlZtT/~3/i9P6CHWUzCU/nitoasyncex-available.html" title="Nito.AsyncEx Available" /><author><name>Stephen Cleary</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://nitoprograms.blogspot.com/2011/09/nitoasyncex-available.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkEEQHY4eCp7ImA9WhdXGEQ.&quot;"><id>tag:blogger.com,1999:blog-7297021906893122222.post-389732469803365909</id><published>2011-09-01T12:30:00.004-04:00</published><updated>2011-09-01T12:30:01.830-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-01T12:30:01.830-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Language design" /><category scheme="http://www.blogger.com/atom/ns#" term="async" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><title>The Async CTP "Why Do the Keywords Work THAT Way" Unofficial FAQ</title><content type="html">&lt;p&gt;There's a lot of interest in the &lt;a href="http://msdn.microsoft.com/en-US/vstudio/async"&gt;Async CTP&lt;/a&gt;, with good reason. The Async CTP will make asynchronous programming much, much easier than it has ever been. It's somewhat less powerful but much easier to learn than &lt;a href="http://msdn.microsoft.com/en-us/data/gg577609"&gt;Rx&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The Async CTP introduces two new keywords, &lt;b&gt;async&lt;/b&gt; and &lt;b&gt;await&lt;/b&gt;. Asynchronous methods (or lambda expressions) must return &lt;b&gt;void&lt;/b&gt;, &lt;b&gt;Task&lt;/b&gt;, or &lt;b&gt;Task&amp;lt;TResult&amp;gt;&lt;/b&gt;.&lt;/p&gt;

&lt;p&gt;This post is not an introduction to the Async CTP; there's plenty of tutorial resources available out there. This post is an attempt to bring together the answers to a few common questions that programmers have when they start using the Async CTP.&lt;/p&gt;

&lt;h4&gt;Inferring the Return Type&lt;/h4&gt;

&lt;p&gt;When returning a value from an &lt;b&gt;async&lt;/b&gt; method, the method body returns the value directly, but the method itself is declared as returning a &lt;b&gt;Task&amp;lt;TResult&amp;gt;&lt;/b&gt;. There is a bit of "disconnect" when you declare a method returning one type and have to return another type:&lt;/p&gt;

&lt;pre class="brush:csharp"&gt;
// Actual syntax
public async Task&amp;lt;int&amp;gt; GetValue()
{
  await TaskEx.Delay(100);
  return 13; // Return type is "int", not "Task&amp;lt;int&amp;gt;"
}
&lt;/pre&gt;

&lt;p&gt;Question: Why can't I write this:&lt;/p&gt;

&lt;pre class="brush:csharp"&gt;
// Hypothetical syntax
public async int GetValue()
{
  await TaskEx.Delay(100);
  return 13; // Return type is "int"
}
&lt;/pre&gt;

&lt;p&gt;Consider: How will the method signature look to callers? Async methods that return a value must have an actual result type of &lt;b&gt;Task&amp;lt;TResult&amp;gt;&lt;/b&gt;. So &lt;b&gt;GetValue&lt;/b&gt; will show up in IntelliSense as returning &lt;b&gt;Task&amp;lt;TResult&amp;gt;&lt;/b&gt; (this would also be true for the object browser, Reflector, etc).&lt;/p&gt;

&lt;p&gt;Inferring the return type &lt;a href="http://social.msdn.microsoft.com/Forums/en-US/async/thread/0ee0af6a-3034-4ac3-aa82-cb6bd62a9ab9#8d1826a5-d603-4b74-8c64-2a9b32d6af24"&gt;was considered&lt;/a&gt; during the initial design, but the team concluded that the keeping the "disconnect" within the &lt;b&gt;async&lt;/b&gt; method was better than spreading the "disconnect" throughout the code base. The "disconnect" is still there, but it's smaller than it could be. The consensus is that a consistent method signature is preferred.&lt;/p&gt;

&lt;p&gt;Consider: There is a difference between &lt;b&gt;async void&lt;/b&gt; and &lt;b&gt;async Task&lt;/b&gt;.&lt;/p&gt;

&lt;p&gt;An &lt;b&gt;async Task&lt;/b&gt; method is just like any other asynchronous operation, only without a return value. An &lt;b&gt;async void&lt;/b&gt; method acts as a "top-level" asynchronous operation. An &lt;b&gt;async Task&lt;/b&gt; method may be composed into other async methods using &lt;b&gt;await&lt;/b&gt;. An &lt;b&gt;async void&lt;/b&gt; method may be used as an event handler. An &lt;b&gt;async void&lt;/b&gt; method also has another important property: in an ASP.NET context, it informs the web server that the page is not completed until it returns (see &lt;a href="http://msdn.microsoft.com/en-us/magazine/gg598924.aspx"&gt;my MSDN article&lt;/a&gt; for more information on how this works).&lt;/p&gt;

&lt;p&gt;Inferring the return type would remove the distinction between &lt;b&gt;async void&lt;/b&gt; and &lt;b&gt;async Task&lt;/b&gt;; either all async methods would be &lt;b&gt;async void&lt;/b&gt; (preventing composability), or they would all be &lt;b&gt;async Task&lt;/b&gt; (preventing them from being event handlers, and requiring an alternative solution for ASP.NET support).&lt;/p&gt;

&lt;h4&gt;Async Return&lt;/h4&gt;

&lt;p&gt;There is still a "disconnect" between the method declaration return type and the method body return type. Another option that &lt;a href="http://gauravsmathur.wordpress.com/2010/11/04/something-wrong-with-async-await-and-the-tasktask/"&gt;has been suggested&lt;/a&gt; is to add a keyword to &lt;b&gt;return&lt;/b&gt; to indicate that the value given to &lt;b&gt;return&lt;/b&gt; is not really what's being returned, e.g.:&lt;/p&gt;

&lt;pre class="brush:csharp"&gt;
// Hypothetical syntax
public async Task&amp;lt;int&amp;gt; GetValue()
{
  await TaskEx.Delay(100);
  async return 13; // "async return" means the value will be wrapped in a Task
}
&lt;/pre&gt;

&lt;p&gt;Consider: Converting large amounts of code from synchronous to asynchronous.&lt;/p&gt;

&lt;p&gt;The &lt;b&gt;async return&lt;/b&gt; keyword &lt;a href="http://social.msdn.microsoft.com/Forums/en-US/async/thread/75493675-4a39-4958-a493-ad8a96f8a19d"&gt;was also considered&lt;/a&gt;, but it wasn't compelling enough. This is particularly true when converting a lot of synchronous code to asynchronous code (which will be common over the next few years); forcing people to add &lt;b&gt;async&lt;/b&gt; to every &lt;b&gt;return&lt;/b&gt; statement just seemed like "needless busy-work." It's easier to get used to the "disconnect".&lt;/p&gt;

&lt;h4&gt;Inferring "async"&lt;/h4&gt;

&lt;p&gt;The &lt;b&gt;async&lt;/b&gt; keyword &lt;i&gt;must&lt;/i&gt; be applied to a method that makes use of &lt;b&gt;await&lt;/b&gt;. However, it also gives a warning if it is applied to a method that does &lt;i&gt;not&lt;/i&gt; make use of &lt;b&gt;await&lt;/b&gt;.&lt;/p&gt;

&lt;p&gt;Question: Why can't &lt;b&gt;async&lt;/b&gt; be inferred based on the presence of &lt;b&gt;await&lt;/b&gt;:&lt;/p&gt;

&lt;pre class="brush:csharp"&gt;
// Hypothetical syntax
public Task&amp;lt;int&amp;gt; GetValue()
{
  // The presence of "await" implies that this is an "async" method.
  await TaskEx.Delay(100);
  return 13;
}
&lt;/pre&gt;

&lt;p&gt;Consider: Backwards compatibility and code readability.&lt;/p&gt;

&lt;p&gt;Eric Lippert has the &lt;a href="http://blogs.msdn.com/b/ericlippert/archive/2010/11/11/whither-async.aspx"&gt;definitive post&lt;/a&gt; on the subject. It's also been discussed in &lt;a href="http://blogs.msdn.com/b/ericlippert/archive/2010/10/29/asynchronous-programming-in-c-5-0-part-two-whence-await.aspx"&gt;blog comments&lt;/a&gt;, &lt;a href="http://channel9.msdn.com/Forums/Coffeehouse/Why-is-the-async-keyword-needed"&gt;Channel9&lt;/a&gt;, and &lt;a href="http://social.msdn.microsoft.com/Forums/en-US/async/thread/75493675-4a39-4958-a493-ad8a96f8a19d"&gt;forums&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To summarize, a single-word &lt;b&gt;await&lt;/b&gt; keyword would be too big of a breaking change. The choice was between a multi-word await (e.g., &lt;b&gt;await for&lt;/b&gt;) or a keyword on the method (&lt;b&gt;async&lt;/b&gt;) that would enable the &lt;b&gt;await&lt;/b&gt; keyword just within that method. Explicitly marking methods &lt;b&gt;async&lt;/b&gt; is easier for both humans and computers to parse, so they decided to go with the &lt;b&gt;async&lt;/b&gt;/&lt;b&gt;await&lt;/b&gt; pair.&lt;/p&gt;

&lt;h4&gt;Inferring "await"&lt;/h4&gt;

&lt;p&gt;Question: Since it makes sense to explicitly include &lt;b&gt;async&lt;/b&gt; (see above), why can't &lt;b&gt;await&lt;/b&gt; be inferred based on the presence of &lt;b&gt;async&lt;/b&gt;:&lt;/p&gt;

&lt;pre class="brush:csharp"&gt;
// Hypothetical syntax
public async Task&amp;lt;int&amp;gt; GetValue()
{
  // "await" is implied, since this is an "async" method.
  TaskEx.Delay(100);
  return 13;
}
&lt;/pre&gt;

&lt;p&gt;Consider: Parallel composition of asynchronous operations.&lt;/p&gt;

&lt;p&gt;At first glance, inferring &lt;b&gt;await&lt;/b&gt; appears to simplify basic asynchronous operations. As long as all waiting is done in serial (i.e., one operation is awaited, then another, and then another), this works fine. However, it falls apart when one considers parallel composition.&lt;/p&gt;

&lt;p&gt;Parallel composition in the Async CTP is done using &lt;b&gt;TaskEx.WhenAny&lt;/b&gt; and &lt;b&gt;TaskEx.WhenAll&lt;/b&gt; methods. Here's a simple example which starts two operations immediately and asynchronously waits for both of them to complete:&lt;/p&gt;

&lt;pre class="brush:csharp"&gt;
// Actual syntax
public async Task&amp;lt;int&amp;gt; GetValue()
{
  // Asynchronously retrieve two partial values.
  // Note that these are *not* awaited at this time.
  Task&amp;lt;int&amp;gt; part1 = GetValuePart1();
  Task&amp;lt;int&amp;gt; part2 = GetValuePart2();

  // Wait for both values to arrive.
  await TaskEx.WhenAll(part1, part2);

  // Calculate our result.
  int value1 = await part1; // Does not actually wait.
  int value2 = await part2; // Does not actually wait.
  return value1 + value2;
}
&lt;/pre&gt;

&lt;p&gt;In order to do parallel composition, we must have the ability to say we're &lt;i&gt;not&lt;/i&gt; going to &lt;b&gt;await&lt;/b&gt; an expression.&lt;/p&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7297021906893122222-389732469803365909?l=nitoprograms.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OlZtT/~4/EiwMHxgQLXc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://nitoprograms.blogspot.com/feeds/389732469803365909/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://nitoprograms.blogspot.com/2011/09/async-ctp-why-do-keywords-work-that-way.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/389732469803365909?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/389732469803365909?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OlZtT/~3/EiwMHxgQLXc/async-ctp-why-do-keywords-work-that-way.html" title="The Async CTP &quot;Why Do the Keywords Work THAT Way&quot; Unofficial FAQ" /><author><name>Stephen Cleary</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://nitoprograms.blogspot.com/2011/09/async-ctp-why-do-keywords-work-that-way.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A08EQng9eCp7ImA9WhdXEkU.&quot;"><id>tag:blogger.com,1999:blog-7297021906893122222.post-6502016124937707996</id><published>2011-08-25T12:30:00.001-04:00</published><updated>2011-08-25T12:30:03.660-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-25T12:30:03.660-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Option Parsing" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="Nito.KitchenSink" /><title>Option Parsing: Validation</title><content type="html">&lt;p&gt;The &lt;a href="http://nitoprograms.blogspot.com/2011/06/option-parsing-option-parsing-pipeline.html"&gt;option parsing pipeline&lt;/a&gt; consists of three steps: lexing, parsing, and validation. So far, we've only talked about the first two steps; today we'll look at validation.&lt;/p&gt;

&lt;p&gt;Option argument classes must derive from &lt;b&gt;IOptionArguments&lt;/b&gt;, which only has one method:&lt;/p&gt;

&lt;pre class="brush:csharp"&gt;
/// &amp;lt;summary&amp;gt;
/// An arguments class, which uses option attributes on its properties.
/// &amp;lt;/summary&amp;gt;
public interface IOptionArguments
{
  /// &amp;lt;summary&amp;gt;
  /// Validates the arguments by throwing &amp;lt;see cref=&amp;quot;OptionParsingException&amp;quot;/&amp;gt; errors as necessary.
  /// &amp;lt;/summary&amp;gt;
  void Validate();
}
&lt;/pre&gt;

&lt;p&gt;The &lt;b&gt;Validate&lt;/b&gt; method should do any validation, and throw an exception if the option argument class properties are not acceptable. The &lt;b&gt;OptionArgumentsBase&lt;/b&gt; type includes an implementation of &lt;b&gt;Validate&lt;/b&gt; that just does some basic validation (we'll cover it in detail next week). This method may be overridden in derived classes.&lt;/p&gt;

&lt;h4&gt;Validating Option Values&lt;/h4&gt;

&lt;p&gt;It's possible to include any logic you need in the &lt;b&gt;Validate&lt;/b&gt; method. This example forces an option value to be in the range [0, 3]:&lt;/p&gt;

&lt;pre class="brush:csharp"&gt;
class Program
{
  private sealed class Options : OptionArgumentsBase
  {
    [Option(&amp;quot;level&amp;quot;, 'l')]
    public int Level { get; set; }

    public override void Validate()
    {
      base.Validate();
      if (this.Level &amp;lt; 0 || this.Level &amp;gt; 3)
        throw new OptionParsingException.OptionArgumentException(&amp;quot;Level must be in the range [0, 3].&amp;quot;);
    }
  }

  static int Main()
  {
    try
    {
      var options = OptionParser.Parse&amp;lt;Options&amp;gt;();

      Console.WriteLine(&amp;quot;Level: &amp;quot; + options.Level);

      return 0;
    }
    catch (OptionParsingException ex)
    {
      Console.Error.WriteLine(ex.Message);
      return 2;
    }
    catch (Exception ex)
    {
      Console.Error.WriteLine(ex);
      return 1;
    }
  }
}
&lt;/pre&gt;

&lt;pre&gt;
&amp;gt; CommandLineParsingTest.exe
Level: 0

&amp;gt; CommandLineParsingTest.exe -l 3
Level: 3

&amp;gt; CommandLineParsingTest.exe -l 4
Level must be in the range [0, 3].
&lt;/pre&gt;

&lt;p&gt;Other option parsing libraries do validation using various attributes (e.g., the example above would use a [RangeAttribute]). However, using a &lt;b&gt;Validate&lt;/b&gt; method is both simpler and more powerful.&lt;/p&gt;

&lt;h4&gt;Required Options&lt;/h4&gt;

&lt;p&gt;It's possible to use validation to &lt;i&gt;require&lt;/i&gt; an option.&lt;/p&gt;

&lt;blockquote&gt;&lt;b&gt;Please note:&lt;/b&gt; The technique described here is controversial! In general, people who have designed many command-line interfaces do not recommend &lt;i&gt;required options&lt;/i&gt; (at the very least, the terminology is confusing: it's a required optional parameter). Usually, a required option is better represented as a positional argument or a subcommand (both of which will be covered in later blog posts). Consider carefully before using required options.&lt;/blockquote&gt;

&lt;p&gt;The example below requires a level to be specified:&lt;/p&gt;

&lt;pre class="brush:csharp"&gt;
class Program
{
  private sealed class Options : OptionArgumentsBase
  {
    [Option(&amp;quot;level&amp;quot;, 'l')]
    public int? Level { get; set; }

    public override void Validate()
    {
      base.Validate();
      if (this.Level == null)
        throw new OptionParsingException.OptionArgumentException(&amp;quot;Level must be specified.&amp;quot;);
    }
  }

  static int Main()
  {
    try
    {
      var options = OptionParser.Parse&amp;lt;Options&amp;gt;();

      Console.WriteLine(&amp;quot;Level: &amp;quot; + options.Level);

      return 0;
    }
    catch (OptionParsingException ex)
    {
      Console.Error.WriteLine(ex.Message);
      return 2;
    }
    catch (Exception ex)
    {
      Console.Error.WriteLine(ex);
      return 1;
    }
  }
}
&lt;/pre&gt;

&lt;pre&gt;
&amp;gt; CommandLineParsingTest.exe
Level must be specified.

&amp;gt; CommandLineParsingTest.exe -l 4
Level: 4

&amp;gt; CommandLineParsingTest.exe -l 0
Level: 0
&lt;/pre&gt;

&lt;p&gt;To reiterate, people with much more experience than I recommend against using "required options". They recommend positional arguments or subcommands instead.&lt;/p&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7297021906893122222-6502016124937707996?l=nitoprograms.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OlZtT/~4/BQUCCPYbHFw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://nitoprograms.blogspot.com/feeds/6502016124937707996/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://nitoprograms.blogspot.com/2011/08/option-parsing-validation.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/6502016124937707996?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/6502016124937707996?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OlZtT/~3/BQUCCPYbHFw/option-parsing-validation.html" title="Option Parsing: Validation" /><author><name>Stephen Cleary</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://nitoprograms.blogspot.com/2011/08/option-parsing-validation.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0cEQ304fCp7ImA9WhdQFkU.&quot;"><id>tag:blogger.com,1999:blog-7297021906893122222.post-5266290140171816250</id><published>2011-08-18T12:30:00.005-04:00</published><updated>2011-08-18T12:30:02.334-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-18T12:30:02.334-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Option Parsing" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="Nito.KitchenSink" /><title>Option Parsing: Boolean Options</title><content type="html">&lt;h4&gt;Options as Flags&lt;/h4&gt;

&lt;p&gt;Most options require an option argument. Some options take &lt;a href="http://nitoprograms.blogspot.com/2011/07/option-parsing-options-with-optional.html"&gt;an optional argument&lt;/a&gt;. Then there are the options that take no argument at all. These are the "flag" options - the option value is either set or unset.&lt;/p&gt;

&lt;p&gt;Options with no arguments may only be defined on boolean properties. Consider this program, which defines two options (&lt;b&gt;a&lt;/b&gt; and &lt;b&gt;b&lt;/b&gt;) that do not take arguments, and a third option (&lt;b&gt;c&lt;/b&gt;) which takes a required argument:&lt;/p&gt;

&lt;pre class="brush:csharp"&gt;
class ProgramtO
{
  private sealed class Options : OptionArgumentsBase
  {
    [Option('a', Argument = OptionArgument.None)]
    public bool A { get; set; }

    [Option('b', Argument = OptionArgument.None)]
    public bool B { get; set; }

    [Option('c')]
    public bool C { get; set; }
  }

  static int Main()
  {
    try
    {
      var options = OptionParser.Parse&amp;lt;Options&amp;gt;();

      Console.WriteLine(&amp;quot;A: &amp;quot; + options.A);
      Console.WriteLine(&amp;quot;B: &amp;quot; + options.B);
      Console.WriteLine(&amp;quot;C: &amp;quot; + options.C);

      return 0;
    }
    catch (OptionParsingException ex)
    {
      Console.Error.WriteLine(ex.Message);
      return 2;
    }
    catch (Exception ex)
    {
      Console.Error.WriteLine(ex);
      return 1;
    }
  }
}
&lt;/pre&gt;

&lt;pre&gt;
&amp;gt; CommandLineParsingTest.exe
A: False
B: False
C: False

&amp;gt; CommandLineParsingTest.exe -a -b
A: True
B: True
C: False

&amp;gt; CommandLineParsingTest.exe -c
Missing argument for option  c

&amp;gt; CommandLineParsingTest.exe -c true
A: False
B: False
C: True
&lt;/pre&gt;

&lt;h4&gt;Short Option Runs&lt;/h4&gt;

&lt;p&gt;Arguments that do not take arguments may be combined on the command line into a "short option run." A short option run must use the short names of the options; it cannot use the long names.&lt;/p&gt;

&lt;pre&gt;
&amp;gt; CommandLineParsingTest.exe -ab
A: True
B: True
C: False
&lt;/pre&gt;

&lt;p&gt;There is no way to pass an argument to an option in a short option run.&lt;/p&gt;

&lt;pre&gt;
&amp;gt; CommandLineParsingTest.exe -ac true
Option  c  cannot be in a short option run (because it takes an argument) in parameter  -ac

&amp;gt; CommandLineParsingTest.exe -ac=true
Invalid parameter  -ac=true
&lt;/pre&gt;

&lt;blockquote&gt;This is a deliberate departure from the behavior of GNU's getopt. Short option runs with arguments are not readable and may cause compatibility problems when the options change.&lt;/blockquote&gt;

&lt;h4&gt;Inverse Aliases&lt;/h4&gt;

&lt;p&gt;Some programs prefer the ability to specify an "on" and an "off" version for the same option. This can be easily done by having the boolean properties share a single backing value, with the "off" version inverting its value. These are very similar to aliases, except that they mean the &lt;i&gt;opposite&lt;/i&gt; instead of the &lt;i&gt;same&lt;/i&gt;.&lt;/p&gt;

&lt;pre class="brush:csharp"&gt;
class Program
{
  private sealed class Options : OptionArgumentsBase
  {
    public Options()
    {
      this.B = true;
    }

    [Option(&amp;quot;a&amp;quot;, Argument = OptionArgument.None)]
    public bool A { get; set; }

    [Option(&amp;quot;no-a&amp;quot;, Argument = OptionArgument.None)]
    public bool NoA
    {
      get { return !this.A; }
      set { this.A = !value; }
    }

    [Option(&amp;quot;b&amp;quot;, Argument = OptionArgument.None)]
    public bool B { get; set; }

    [Option(&amp;quot;no-b&amp;quot;, Argument = OptionArgument.None)]
    public bool NoB
    {
      get { return !this.B; }
      set { this.B = !value; }
    }
  }

  static int Main()
  {
    try
    {
      var options = OptionParser.Parse&amp;lt;Options&amp;gt;();

      Console.WriteLine(&amp;quot;A: &amp;quot; + options.A);
      Console.WriteLine(&amp;quot;B: &amp;quot; + options.B);

      return 0;
    }
    catch (OptionParsingException ex)
    {
      Console.Error.WriteLine(ex.Message);
      return 2;
    }
    catch (Exception ex)
    {
      Console.Error.WriteLine(ex);
      return 1;
    }
  }
}
&lt;/pre&gt;

&lt;pre&gt;
&amp;gt; CommandLineParsingTest.exe
A: False
B: True

&amp;gt; CommandLineParsingTest.exe /a
A: True
B: True

&amp;gt; CommandLineParsingTest.exe /b
A: False
B: True

&amp;gt; CommandLineParsingTest.exe /no-a
A: False
B: True

&amp;gt; CommandLineParsingTest.exe /no-b
A: False
B: False

&amp;gt; CommandLineParsingTest.exe /a /no-a
A: False
B: True
&lt;/pre&gt;

&lt;p&gt;The last example shows that the default &lt;a href="http://nitoprograms.blogspot.com/2011/08/option-parsing-preventing-multiple.html"&gt;overwrite behavior&lt;/a&gt; of options produces the expected result: when there are multiple conflicting options on a command line, the last one wins.&lt;/p&gt;

&lt;p&gt;Note that the options in this sample do not have short names. They &lt;i&gt;are&lt;/i&gt; allowed to have short names, but options with inverse aliases do not usually have short names.&lt;/p&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7297021906893122222-5266290140171816250?l=nitoprograms.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OlZtT/~4/6w3uVXOieb0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://nitoprograms.blogspot.com/feeds/5266290140171816250/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://nitoprograms.blogspot.com/2011/08/option-parsing-boolean-options.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/5266290140171816250?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/5266290140171816250?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OlZtT/~3/6w3uVXOieb0/option-parsing-boolean-options.html" title="Option Parsing: Boolean Options" /><author><name>Stephen Cleary</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://nitoprograms.blogspot.com/2011/08/option-parsing-boolean-options.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0MASHo6fCp7ImA9WhdQEUs.&quot;"><id>tag:blogger.com,1999:blog-7297021906893122222.post-6819626154390642976</id><published>2011-08-11T12:30:00.020-04:00</published><updated>2011-08-12T11:04:09.414-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-12T11:04:09.414-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Option Parsing" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="Nito.KitchenSink" /><title>Option Parsing: Argument Parsing</title><content type="html">&lt;p&gt;This is going to be an in-depth post on how argument parsing works in the &lt;a href="http://nuget.org/List/Packages/Nito.KitchenSink.OptionParsing"&gt;Nito.KitchenSink.OptionParsing library&lt;/a&gt;, and a couple of ways the parsing can be modified.&lt;/p&gt;

&lt;h4&gt;General Option Argument Parsing Rules&lt;/h4&gt;

&lt;p&gt;First, a reminder about terminology; in this example, the "v" is the short option name, and the "3" is the option argument:&lt;/p&gt;

&lt;pre&gt;&amp;gt; CommandLineTest.exe -v 3&lt;/pre&gt;

&lt;p&gt;Also remember that an option argument may be &lt;i&gt;required&lt;/i&gt; for an option, or it may be &lt;i&gt;optional&lt;/i&gt;. If you need a refresher, read the earlier post &lt;a href="http://nitoprograms.blogspot.com/2011/07/option-parsing-options-with-optional.html"&gt;options with optional arguments&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Required option arguments are allowed to begin with a dash (&lt;b&gt;-&lt;/b&gt;) or forward-slash (&lt;b&gt;/&lt;/b&gt;), but optional option arguments are not. To start an optional option argument with these characters, specify the argument using a full-colon (&lt;b&gt;:&lt;/b&gt;) or equals sign (&lt;b&gt;=&lt;/b&gt;).&lt;/p&gt;

&lt;p&gt;Consider this example program, which just takes two string arguments, one required and one optional:&lt;/p&gt;

&lt;pre class="brush:csharp"&gt;
class Program
{
  private sealed class Options : OptionArgumentsBase
  {
    [Option(&amp;quot;required&amp;quot;, 'r')]
    public string RequiredValue { get; set; }

    [Option(&amp;quot;optional&amp;quot;, 'o', Argument = OptionArgument.Optional)]
    public string OptionalValue { get; set; }
  }

  static int Main()
  {
    try
    {
      var options = OptionParser.Parse&amp;lt;Options&amp;gt;();

      if (options.RequiredValue != null)
        Console.WriteLine(&amp;quot;Required Value: &amp;quot; + options.RequiredValue);
      if (options.OptionalValue != null)
        Console.WriteLine(&amp;quot;Optional Value: &amp;quot; + options.OptionalValue);

      return 0;
    }
    catch (OptionParsingException ex)
    {
      Console.Error.WriteLine(ex.Message);
      return 2;
    }
    catch (Exception ex)
    {
      Console.Error.WriteLine(ex);
      return 1;
    }
  }
}
&lt;/pre&gt;

&lt;pre&gt;
&amp;gt; CommandLineParsingTest.exe -r a -o b
Required Value: a
Optional Value: b

&amp;gt; CommandLineParsingTest.exe -r /a -o b
Required Value: /a
Optional Value: b

&amp;gt; CommandLineParsingTest.exe -r a -o /b
Unknown option  b  in parameter  /b

&amp;gt; CommandLineParsingTest.exe -o &amp;quot;/b&amp;quot;
Unknown option  b  in parameter  /b

&amp;gt; CommandLineParsingTest.exe -o:/b
Optional Value: /b

&amp;gt; CommandLineParsingTest.exe -o=/b
Optional Value: /b
&lt;/pre&gt;

&lt;p&gt;Note that placing the argument in double-quotes does &lt;i&gt;not&lt;/i&gt; allow the argument to start with a dash or forward-slash.&lt;/p&gt;

&lt;p&gt;Reminder: the command shell has its own set of reserved characters (&lt;b&gt;&amp;amp;&lt;/b&gt;, &lt;b&gt;|&lt;/b&gt;, &lt;b&gt;(&lt;/b&gt;, &lt;b&gt;)&lt;/b&gt;, &lt;b&gt;&amp;lt;&lt;/b&gt;, &lt;b&gt;&amp;gt;&lt;/b&gt;, and &lt;b&gt;^&lt;/b&gt;). These can be escaped using &lt;b&gt;^&lt;/b&gt;, or they can be wrapped in double-quotes. Command shell escapes are described in more detail in the &lt;a href="http://nitoprograms.blogspot.com/2011/06/option-parsing-lexing.html"&gt;post on command-line lexing&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;Implementing a Simple Argument Parser&lt;/h4&gt;

&lt;p&gt;Parsing an argument option is done in two steps. The first step is to parse that portion of the command line as a string, using the rules above. The second step is to parse the string into an instance of the corresponding property type on the option arguments class. Since the examples above used a property type of string, there was no processing during the second step.&lt;/p&gt;

&lt;blockquote&gt;It is possible to use only a part of the &lt;a href="http://nitoprograms.blogspot.com/2011/06/option-parsing-option-parsing-pipeline.html"&gt;option parsing pipeline&lt;/a&gt; to get options and their arguments as strings. Pass a sequence of &lt;b&gt;OptionDefinition&lt;/b&gt; instancess and a command line into the parser; the result is a sequence of &lt;b&gt;Option&lt;/b&gt; instances (where each argument is typed as &lt;b&gt;string&lt;/b&gt;). Details of these types will be covered in a future blog post.&lt;/blockquote&gt;

&lt;p&gt;The option parsing library uses a collection of "simple parsers" to convert from a string to a known type. By default, the simple parser collection understands how to parse &lt;b&gt;bool&lt;/b&gt;; signed and unsigned 8-bit, 16-bit, 32-bit, and 64-bit integers; &lt;b&gt;BigInteger&lt;/b&gt;; single and double-precision floating point; &lt;b&gt;decimal&lt;/b&gt;; &lt;b&gt;Guid&lt;/b&gt;; &lt;b&gt;TimeSpan&lt;/b&gt;; &lt;b&gt;DateTime&lt;/b&gt;; and &lt;b&gt;DateTimeOffset&lt;/b&gt;. Strings, enumerations and nullable types are treated specially: strings are never parsed, enumerations use &lt;b&gt;Enum.Parse&lt;/b&gt;, and nullable types are supported if their corresponding non-nullable types are supported. The built-in parsers all use the standard &lt;b&gt;TryParse&lt;/b&gt; methods.&lt;/p&gt;

&lt;p&gt;Say, for example, we wanted to accept an argument of type &lt;a href="http://msdn.microsoft.com/en-us/library/system.numerics.complex.aspx"&gt;Complex&lt;/a&gt;. The Complex type is not included in the default simple parser collection (in fact, it does not even have a Parse or TryParse method!).&lt;/p&gt;

&lt;p&gt;If we try to add it to our program, then whatever we pass as the argument value will just fail to parse:&lt;/p&gt;

&lt;pre class="brush:csharp"&gt;
class Program
{
  private sealed class Options : OptionArgumentsBase
  {
    [Option(&amp;quot;value&amp;quot;, 'v')]
    public Complex? Value { get; set; }
  }

  static int Main()
  {
    try
    {
      var options = OptionParser.Parse&amp;lt;Options&amp;gt;();

      if (options.Value != null)
        Console.WriteLine(&amp;quot;Value: &amp;quot; + options.Value);

      return 0;
    }
    catch (OptionParsingException ex)
    {
      Console.Error.WriteLine(ex.Message);
      return 2;
    }
    catch (Exception ex)
    {
      Console.Error.WriteLine(ex);
      return 1;
    }
  }
}
&lt;/pre&gt;

&lt;pre&gt;
&amp;gt; CommandLineParsingTest.exe -v (3,5)
Could not parse  (3,5)  as Complex
&lt;/pre&gt;

&lt;p&gt;We can create a parser for the &lt;b&gt;Complex&lt;/b&gt; type by implementing &lt;b&gt;ISimpleParser&lt;/b&gt;. This interface only has two members: the type of the result and a &lt;b&gt;TryParse&lt;/b&gt; method.&lt;/p&gt;

&lt;p&gt;Once we've implemented our special parser, we need to pass it to the Parse method. To do this, we create a &lt;b&gt;SimpleParserCollection&lt;/b&gt;, add our special parser, and pass the collection to the Parse method.&lt;/p&gt;

&lt;p&gt;Our solution now looks like this:&lt;/p&gt;

&lt;pre class="brush:csharp"&gt;
class Program
{
  private sealed class ComplexParser : ISimpleParser
  {
    public Type ResultType
    {
      get { return typeof(Complex); }
    }

    public object TryParse(string value)
    {
      // Match the following pattern: '(' double ',' double ')'
      if (value.Length &amp;lt; 5 || value[0] != '(' || value[value.Length - 1] != ')')
        return null;
      var components = value.Substring(1, value.Length - 2).Split(',');
      if (components.Length != 2)
        return null;
      double real, imaginary;
      if (!double.TryParse(components[0], out real))
        return null;
      if (!double.TryParse(components[1], out imaginary))
        return null;
      return new Complex(real, imaginary);
    }
  }


  private sealed class Options : OptionArgumentsBase
  {
    [Option(&amp;quot;value&amp;quot;, 'v')]
    public Complex? Value { get; set; }
  }

  static int Main()
  {
    try
    {
      var parsers = new SimpleParserCollection();
      parsers.Add(new ComplexParser());
      var options = OptionParser.Parse&amp;lt;Options&amp;gt;(parserCollection: parsers);

      if (options.Value != null)
        Console.WriteLine(&amp;quot;Value: &amp;quot; + options.Value);

      return 0;
    }
    catch (OptionParsingException ex)
    {
      Console.Error.WriteLine(ex.Message);
      return 2;
    }
    catch (Exception ex)
    {
      Console.Error.WriteLine(ex);
      return 1;
    }
  }
}
&lt;/pre&gt;

&lt;pre&gt;
&amp;gt; CommandLineParsingTest.exe -v (3,5)
Value: (3, 5)
&lt;/pre&gt;

&lt;p&gt;We added a custom parser to the collection, and the option parsing library now understands how to parse a new type. We could add any number of &lt;b&gt;Complex&lt;/b&gt; properties, and they would all use the new parser.&lt;/p&gt;

&lt;p&gt;This is a powerful extension point, but what if we want to modify the way an extisting type is parsed?&lt;/p&gt;

&lt;h4&gt;Replacing a Simple Argument Parser&lt;/h4&gt;

&lt;p&gt;The default parsers in a simple parser collection only use the basic &lt;b&gt;TryParse&lt;/b&gt; methods, which may not be exactly what is needed. &lt;b&gt;SimpleParserCollection.Add&lt;/b&gt; will actually &lt;i&gt;replace&lt;/i&gt; the parser for a given type if there is already a parser for that type.&lt;/p&gt;

&lt;p&gt;We'll use &lt;b&gt;uint&lt;/b&gt; for our example. We want to allow either decimal numbers or hexadecimal numbers prefixed by "0x". &lt;b&gt;System.UInt32.TryParse(string)&lt;/b&gt; does not accept hexadecimal numbers:&lt;/p&gt;

&lt;pre class="brush:csharp"&gt;
class Program
{
  private sealed class Options : OptionArgumentsBase
  {
    [Option(&amp;quot;value&amp;quot;, 'v')]
    public uint? Value { get; set; }
  }

  static int Main()
  {
    try
    {
      var options = OptionParser.Parse&amp;lt;Options&amp;gt;();

      if (options.Value != null)
        Console.WriteLine(&amp;quot;Value: &amp;quot; + options.Value);

      return 0;
    }
    catch (OptionParsingException ex)
    {
      Console.Error.WriteLine(ex.Message);
      return 2;
    }
    catch (Exception ex)
    {
      Console.Error.WriteLine(ex);
      return 1;
    }
  }
}
&lt;/pre&gt;

&lt;pre&gt;
&amp;gt; CommandLineParsingTest.exe -v 11
Value: 11

&amp;gt; CommandLineParsingTest.exe -v 0x11
Could not parse  0x11  as UInt32
&lt;/pre&gt;

&lt;p&gt;Just like the last example, we'll implement our own parser, and we'll add it to the parser collection (replacing the default parser).&lt;/p&gt;

&lt;pre class="brush:csharp"&gt;
class Program
{
  private sealed class UInt32HexParser : ISimpleParser
  {
    public Type ResultType
    {
      get { return typeof(uint); }
    }

    public object TryParse(string value)
    {
      uint ret;
      if (value.StartsWith(&amp;quot;0x&amp;quot;))
      {
        if (!uint.TryParse(value.Substring(2), NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out ret))
          return null;
        return ret;
      }

      if (!uint.TryParse(value, out ret))
        return null;
      return ret;
    }
  }

  private sealed class Options : OptionArgumentsBase
  {
    [Option(&amp;quot;value&amp;quot;, 'v')]
    public uint? Value { get; set; }
  }

  static int Main()
  {
    try
    {
      var parsers = new SimpleParserCollection();
      parsers.Add(new UInt32HexParser());
      var options = OptionParser.Parse&amp;lt;Options&amp;gt;(parserCollection: parsers);

      if (options.Value != null)
        Console.WriteLine(&amp;quot;Value: &amp;quot; + options.Value);

      return 0;
    }
    catch (OptionParsingException ex)
    {
      Console.Error.WriteLine(ex.Message);
      return 2;
    }
    catch (Exception ex)
    {
      Console.Error.WriteLine(ex);
      return 1;
    }
  }
}
&lt;/pre&gt;

&lt;pre&gt;
&amp;gt; CommandLineParsingTest.exe -v 11
Value: 11

&amp;gt; CommandLineParsingTest.exe -v 0x11
Value: 17
&lt;/pre&gt;

&lt;p&gt;Our program now allows decimal or hexadecimal values for all &lt;b&gt;uint&lt;/b&gt; argument values.&lt;/p&gt;

&lt;p&gt;These custom parsers can be written for any type, including types specific for your program. The only type they won't work on is string, since the simple parser collection just passes string values straight through.&lt;/p&gt;

&lt;h4&gt;Overriding the Simple Argument Parser&lt;/h4&gt;

&lt;p&gt;The examples so far have implemented a custom parser and added it to the parser collection. This changes the parsing behavior for &lt;i&gt;every&lt;/i&gt; property of that type. Sometimes we just want to apply a parser to a single property; this can be done by using the &lt;b&gt;SimpleParserAttribute&lt;/b&gt;.&lt;/p&gt;

&lt;p&gt;This example defines a hex parser (without the "0x" prefix) and then uses it for only one of its properties:&lt;/p&gt;

&lt;pre class="brush:csharp"&gt;
class Program
{
  private sealed class UInt32HexParser : ISimpleParser
  {
    public Type ResultType
    {
      get { return typeof(uint); }
    }

    public object TryParse(string value)
    {
      uint ret;
      if (!uint.TryParse(value, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out ret))
        return null;
      return ret;
    }
  }

  private sealed class Options : OptionArgumentsBase
  {
    [Option(&amp;quot;hex-value&amp;quot;, 'h')]
    [SimpleParser(typeof(UInt32HexParser))]
    public uint? HexValue { get; set; }

    [Option(&amp;quot;dec-value&amp;quot;, 'd')]
    public uint? DecValue { get; set; }
  }

  static int Main()
  {
    try
    {
      var options = OptionParser.Parse&amp;lt;Options&amp;gt;();

      if (options.HexValue != null)
        Console.WriteLine(&amp;quot;HexValue: &amp;quot; + options.HexValue);
      if (options.DecValue != null)
        Console.WriteLine(&amp;quot;DecValue: &amp;quot; + options.DecValue);

      return 0;
    }
    catch (OptionParsingException ex)
    {
      Console.Error.WriteLine(ex.Message);
      return 2;
    }
    catch (Exception ex)
    {
      Console.Error.WriteLine(ex);
      return 1;
    }
  }
}
&lt;/pre&gt;

&lt;pre&gt;
&amp;gt; CommandLineParsingTest.exe -h 11 -d 11
HexValue: 17
DecValue: 11
&lt;/pre&gt;

&lt;h4&gt;Custom Parsers for Multiple Argument Values&lt;/h4&gt;

&lt;p&gt;Revisiting the problem of &lt;a href="http://nitoprograms.blogspot.com/2011/07/option-parsing-allowing-multiple.html"&gt;multiple argument values&lt;/a&gt;, we can use a custom parser for a cleaner solution. This example "sequence parser" uses the default simple parser for &lt;b&gt;int&lt;/b&gt; types, which is easier to deal with than &lt;b&gt;int.TryParse&lt;/b&gt;:&lt;/p&gt;

&lt;pre class="brush:csharp"&gt;
class Program
{
  private sealed class Int32SequenceParser : ISimpleParser
  {
    public Type ResultType
    {
      get { return typeof(IEnumerable&amp;lt;int&amp;gt;); }
    }

    public object TryParse(string value)
    {
      var values = value.Split(',');
      ISimpleParser defaultParser = new DefaultSimpleParser&amp;lt;int&amp;gt;();
      var result = values.Select(x =&amp;gt; defaultParser.TryParse(x));
      if (result.Any(x =&amp;gt; x == null))
        return null;
      return result.Cast&amp;lt;int&amp;gt;();
    }
  }

  private sealed class Options : OptionArgumentsBase
  {
    [Option(&amp;quot;values&amp;quot;, 'v')]
    [SimpleParser(typeof(Int32SequenceParser))]
    public IEnumerable&amp;lt;int&amp;gt; Values { get; set; }
  }

  static int Main()
  {
    try
    {
      var options = OptionParser.Parse&amp;lt;Options&amp;gt;();

      if (options.Values != null)
        Console.WriteLine(&amp;quot;Values: &amp;quot; + string.Join(&amp;quot; &amp;quot;, options.Values));

      return 0;
    }
    catch (OptionParsingException ex)
    {
      Console.Error.WriteLine(ex.Message);
      return 2;
    }
    catch (Exception ex)
    {
      Console.Error.WriteLine(ex);
      return 1;
    }
  }
}
&lt;/pre&gt;

&lt;pre&gt;
&amp;gt; CommandLineParsingTest.exe

&amp;gt; CommandLineParsingTest.exe -v 2,3,5,7
Values: 2 3 5 7

&amp;gt; CommandLineParsingTest.exe -v 2,3a,5
Could not parse  2,3a,5  as IEnumerable&lt;Int32&gt;

&amp;gt; CommandLineParsingTest.exe -v 2,3 -v 5,7
Values: 5 7
&lt;/pre&gt;

&lt;p&gt;The last example above shows that the default behavior of the actual property setter is still &lt;i&gt;overwrite&lt;/i&gt;, not &lt;i&gt;append&lt;/i&gt;. If you want to allow appending sequences, you'll need to change the setter to append each sequence to an internal collection.&lt;/p&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7297021906893122222-6819626154390642976?l=nitoprograms.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OlZtT/~4/2F2xWpPfHqI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://nitoprograms.blogspot.com/feeds/6819626154390642976/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://nitoprograms.blogspot.com/2011/08/option-parsing-argument-parsing.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/6819626154390642976?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/6819626154390642976?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OlZtT/~3/2F2xWpPfHqI/option-parsing-argument-parsing.html" title="Option Parsing: Argument Parsing" /><author><name>Stephen Cleary</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://nitoprograms.blogspot.com/2011/08/option-parsing-argument-parsing.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0MEQX4-fyp7ImA9WhdRFEo.&quot;"><id>tag:blogger.com,1999:blog-7297021906893122222.post-9088134259592323615</id><published>2011-08-04T12:30:00.012-04:00</published><updated>2011-08-04T12:30:00.057-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-04T12:30:00.057-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Option Parsing" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="Nito.KitchenSink" /><title>Option Parsing: Preventing Multiple Argument Values</title><content type="html">&lt;p&gt;When dealing with multiple argument values, there are four basic behaviors: &lt;i&gt;overwrite&lt;/i&gt;, &lt;i&gt;append&lt;/i&gt;, &lt;i&gt;prevent&lt;/i&gt;, and &lt;i&gt;ignore&lt;/i&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://nitoprograms.blogspot.com/2011/07/option-parsing-allowing-multiple.html"&gt;Last week's post&lt;/a&gt; contained a few examples of the &lt;i&gt;append&lt;/i&gt; behavior, which is supported by having the property setter place the values into a backing list.&lt;/p&gt;

&lt;p&gt;The default behavior in the &lt;a href="http://nuget.org/List/Packages/Nito.KitchenSink.OptionParsing"&gt;Nito.KitchenSink option parsing library&lt;/a&gt; is to &lt;i&gt;overwrite&lt;/i&gt; previous values. In other words, options coming later on the command line may "override" options earlier on the command line. Consider this example:&lt;/p&gt;

&lt;pre class="brush:csharp"&gt;
class Program
{
  private sealed class Options : OptionArgumentsBase
  {
    [Option(&amp;quot;level&amp;quot;, 'l')]
    public int? Level { get; set; }
  }

  static int Main()
  {
    try
    {
      var options = OptionParser.Parse&amp;lt;Options&amp;gt;();

      Console.WriteLine(&amp;quot;Level: &amp;quot; + options.Level);

      return 0;
    }
    catch (OptionParsingException ex)
    {
      Console.Error.WriteLine(ex.Message);
      return 2;
    }
    catch (Exception ex)
    {
      Console.Error.WriteLine(ex);
      return 1;
    }
  }
}
&lt;/pre&gt;

&lt;pre&gt;
&amp;gt; CommandLineParsingTest.exe
Level:

&amp;gt; CommandLineParsingTest.exe -l 3
Level: 3

&amp;gt; CommandLineParsingTest.exe -l 3 -l 9
Level: 9
&lt;/pre&gt;

&lt;p&gt;This is the default behavior, and is probably what users expect. However, for some options, the &lt;i&gt;prevent&lt;/i&gt; or &lt;i&gt;ignore&lt;/i&gt; behaviors may make sense.&lt;/p&gt;

&lt;p&gt;The &lt;i&gt;prevent&lt;/i&gt; and &lt;i&gt;ignore&lt;/i&gt; behaviors are closely related. Like last week's post, these behaviors are implemented by placing special code in the property setter.&lt;/p&gt;

&lt;p&gt;The &lt;i&gt;prevent&lt;/i&gt; behavior can be implemented by having a nullable backing value, and throwing from the setter if it is already set. The only tricky part is choosing the exception to throw from the setter; I recommend throwing an exception derived from &lt;b&gt;OptionParsingException&lt;/b&gt;, since that indicates a usage error. Any exception thrown from a property setter will be wrapped in an &lt;b&gt;OptionParsingException.OptionArgumentException&lt;/b&gt; (in versions 1.1.2 and newer).&lt;/p&gt;

&lt;pre class="brush:csharp"&gt;
class Program
{
  private sealed class Options : OptionArgumentsBase
  {
    private int? level;

    [Option(&amp;quot;level&amp;quot;, 'l')]
    public int? Level
    {
      get
      {
        return this.level;
      }

      set
      {
        if (this.level.HasValue)
          throw new OptionParsingException.OptionArgumentException(&amp;quot;The value may only be specified once.&amp;quot;);
        this.level = value;
      }
    }
  }

  static int Main()
  {
    try
    {
      var options = OptionParser.Parse&amp;lt;Options&amp;gt;();

      Console.WriteLine(&amp;quot;Level: &amp;quot; + options.Level);

      return 0;
    }
    catch (OptionParsingException ex)
    {
      Console.Error.WriteLine(ex.Message);
      return 2;
    }
    catch (Exception ex)
    {
      Console.Error.WriteLine(ex);
      return 1;
    }
  }
}
&lt;/pre&gt;

&lt;pre&gt;
&amp;gt; CommandLineParsingTest.exe
Level:

&amp;gt; CommandLineParsingTest.exe -l 3
Level: 3

&amp;gt; CommandLineParsingTest.exe -l 3 -l 9
The value may only be specified once.
&lt;/pre&gt;

&lt;p&gt;Likewise, the &lt;i&gt;ignore&lt;/i&gt; behavior can be implemented by having a nullable backing value, and ignoring the setter if it is already set:&lt;/p&gt;

&lt;pre class="brush:csharp"&gt;
class Program
{
  private sealed class Options : OptionArgumentsBase
  {
    private int? level;

    [Option(&amp;quot;level&amp;quot;, 'l')]
    public int? Level
    {
      get
      {
        return this.level;
      }

      set
      {
        if (!this.level.HasValue)
          this.level = value;
      }
    }
  }

  static int Main()
  {
    try
    {
      var options = OptionParser.Parse&amp;lt;Options&amp;gt;();

      Console.WriteLine(&amp;quot;Level: &amp;quot; + options.Level);

      return 0;
    }
    catch (OptionParsingException ex)
    {
      Console.Error.WriteLine(ex.Message);
      return 2;
    }
    catch (Exception ex)
    {
      Console.Error.WriteLine(ex);
      return 1;
    }
  }
}
&lt;/pre&gt;

&lt;pre&gt;
&amp;gt; CommandLineParsingTest.exe
Level:

&amp;gt; CommandLineParsingTest.exe -l 3
Level: 3

&amp;gt; CommandLineParsingTest.exe -l 3 -l 9
Level: 3
&lt;/pre&gt;

&lt;p&gt;Note that the &lt;i&gt;ignore&lt;/i&gt; behavior may confuse users; most command-line programs use &lt;i&gt;overwrite&lt;/i&gt; behavior, which is the default.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7297021906893122222-9088134259592323615?l=nitoprograms.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OlZtT/~4/eIb3H2SEm6c" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://nitoprograms.blogspot.com/feeds/9088134259592323615/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://nitoprograms.blogspot.com/2011/08/option-parsing-preventing-multiple.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/9088134259592323615?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/9088134259592323615?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OlZtT/~3/eIb3H2SEm6c/option-parsing-preventing-multiple.html" title="Option Parsing: Preventing Multiple Argument Values" /><author><name>Stephen Cleary</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://nitoprograms.blogspot.com/2011/08/option-parsing-preventing-multiple.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0AARH47eip7ImA9WhdQEUs.&quot;"><id>tag:blogger.com,1999:blog-7297021906893122222.post-6186360930312199003</id><published>2011-07-28T12:30:00.007-04:00</published><updated>2011-08-12T11:09:05.002-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-12T11:09:05.002-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Option Parsing" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="Nito.KitchenSink" /><title>Option Parsing: Allowing Multiple Argument Values</title><content type="html">&lt;p&gt;Some options need to take a &lt;i&gt;sequence&lt;/i&gt; of argument values. There are several ways to accomplish this using the &lt;a href="http://nuget.org/List/Packages/Nito.KitchenSink.OptionParsing"&gt;Nito.KitchenSink Option Parsing library&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;Enumeration Flags&lt;/h4&gt;

&lt;p&gt;If the option values are a series of enumerated flags, then the built-in enumeration parser will handle multiple values automatically:&lt;/p&gt;

&lt;pre class="brush:csharp"&gt;
class Program
{
  [Flags]
  private enum FavoriteThings
  {
    None = 0x0,
    Mittens = 0x1,
    Kittens = 0x2,
    Snowflakes = 0x4,
  }

  private sealed class Options : OptionArgumentsBase
  {
    [Option("favorite-things", 'f')]
    public FavoriteThings FavoriteThings { get; set; }
  }

  static int Main()
  {
    try
    {
      var options = OptionParser.Parse&amp;lt;Options&amp;gt;();

      Console.WriteLine(options.FavoriteThings);

      return 0;
    }
    catch (OptionParsingException ex)
    {
      Console.Error.WriteLine(ex.Message);
      return 2;
    }
    catch (Exception ex)
    {
      Console.Error.WriteLine(ex);
      return 1;
    }
  }
}
&lt;/pre&gt;

&lt;pre&gt;
&amp;gt; CommandLineParsingTest.exe
None

&amp;gt; CommandLineParsingTest.exe /favorite-things Mittens
Mittens

&amp;gt; CommandLineParsingTest.exe /favorite-things Mittens,Kittens
Mittens, Kittens

&amp;gt; CommandLineParsingTest.exe /favorite-things "Mittens, Snowflakes"
Mittens, Snowflakes

&amp;gt; CommandLineParsingTest.exe /favorite-things DogBites
Could not parse  DogBites  as FavoriteThings
&lt;/pre&gt;

&lt;h4&gt;Using a Property Setter for Individual Values&lt;/h4&gt;

&lt;p&gt;The example above works well enough for enumerations, but not all arguments are that simple. In these situations, we can take advantage of the fact that arguments are applied to the options class by property setters.&lt;/p&gt;

&lt;p&gt;The following example allows multiple individual values for an argument. As each argument value is set, it is saved into a collection of values.&lt;/p&gt;

&lt;p&gt;Note that using a property setter in this fashion is not a good OOP practice; however, the adverse design affects are contained within the options class.&lt;/p&gt;

&lt;pre class="brush:csharp"&gt;
class Program
{
  private sealed class Options : OptionArgumentsBase
  {
    public Options()
    {
      Numbers = new List&amp;lt;int&amp;gt;();
    }

    public List&amp;lt;int&amp;gt; Numbers { get; private set; }

    [Option("number", 'n')]
    public int NumberOption
    {
      set
      {
        Numbers.Add(value);
      }
    }
  }

  static int Main()
  {
    try
    {
      var options = OptionParser.Parse&amp;lt;Options&amp;gt;();

      Console.WriteLine(string.Join(", ", options.Numbers));

      return 0;
    }
    catch (OptionParsingException ex)
    {
      Console.Error.WriteLine(ex.Message);
      return 2;
    }
    catch (Exception ex)
    {
      Console.Error.WriteLine(ex);
      return 1;
    }
  }
}
&lt;/pre&gt;

&lt;pre&gt;
&amp;gt; CommandLineParsingTest.exe


&amp;gt; CommandLineParsingTest.exe -n 3
3

&amp;gt; CommandLineParsingTest.exe -n 3 -n 6
3, 6

&amp;gt; CommandLineParsingTest.exe -n 3,6
Could not parse  3,6  as Int32
&lt;/pre&gt;

&lt;p&gt;Note that the last test failed; the options class above only allows multiple individual arguments, not a group of values.&lt;/p&gt;

&lt;h4&gt;Using a Property Setter for Grouped Values&lt;/h4&gt;

&lt;p&gt;In this case, we want to be able to pass a sequence of values (delimited somehow) as a single argument, and have them interpreted as multiple individual values.&lt;/p&gt;

&lt;p&gt;We can again take advantage of the property setter hack, but we have to do our own parsing of the delimited value. We will use a property type of &lt;b&gt;string&lt;/b&gt; to prevent automatic parsing.&lt;/p&gt;

&lt;pre class="brush:csharp"&gt;
class Program
{
  private sealed class Options : OptionArgumentsBase
  {
    public Options()
    {
      Numbers = new List&amp;lt;int&amp;gt;();
    }

    public List&amp;lt;int&amp;gt; Numbers { get; private set; }

    [Option("number", 'n')]
    public string NumberOption
    {
      set
      {
        // Note: this example uses poor error handling!
        //  We *should* use TryParse and throw OptionParsingException.
        Numbers.AddRange(value.Split(';').Select(x =&amp;gt; int.Parse(x)));
      }
    }
  }

  static int Main()
  {
    try
    {
      var options = OptionParser.Parse&amp;lt;Options&amp;gt;();

      Console.WriteLine(string.Join(", ", options.Numbers));

      return 0;
    }
    catch (OptionParsingException ex)
    {
      Console.Error.WriteLine(ex.Message);
      return 2;
    }
    catch (Exception ex)
    {
      Console.Error.WriteLine(ex);
      return 1;
    }
  }
}
&lt;/pre&gt;

&lt;pre&gt;
&amp;gt; CommandLineParsingTest.exe -n 3 -n 6
3, 6

&amp;gt; CommandLineParsingTest.exe -n 3;6
3, 6
&lt;/pre&gt;

&lt;p&gt;This works, but still feels a bit "hackish". We're out of time for today, but in &lt;a href="http://nitoprograms.blogspot.com/2011/08/option-parsing-argument-parsing.html"&gt;a few weeks&lt;/a&gt; we'll revisit this problem when we talk about &lt;i&gt;custom argument parsers&lt;/i&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7297021906893122222-6186360930312199003?l=nitoprograms.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OlZtT/~4/AfPTUGeZHs4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://nitoprograms.blogspot.com/feeds/6186360930312199003/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://nitoprograms.blogspot.com/2011/07/option-parsing-allowing-multiple.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/6186360930312199003?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/6186360930312199003?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OlZtT/~3/AfPTUGeZHs4/option-parsing-allowing-multiple.html" title="Option Parsing: Allowing Multiple Argument Values" /><author><name>Stephen Cleary</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://nitoprograms.blogspot.com/2011/07/option-parsing-allowing-multiple.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D08EQX87eSp7ImA9WhdSEks.&quot;"><id>tag:blogger.com,1999:blog-7297021906893122222.post-6342580608716459520</id><published>2011-07-21T12:30:00.005-04:00</published><updated>2011-07-21T12:30:00.101-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-07-21T12:30:00.101-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="callbacks" /><title>System.Threading.Timer Constructor and Garbage Collection</title><content type="html">&lt;p&gt;This week, we take a break from the option parsing posts to bring you an interesting corner case from the BCL.&lt;/p&gt;

&lt;p&gt;The &lt;a href="http://msdn.microsoft.com/en-us/library/1k93acx8.aspx"&gt;System.Threading.Timer constructor&lt;/a&gt; has several overloads; all except one take a &lt;i&gt;state&lt;/i&gt; parameter which is passed to the &lt;i&gt;TimerCallback&lt;/i&gt; delegate when the timer fires.&lt;/p&gt;

&lt;p&gt;It turns out that this &lt;i&gt;state&lt;/i&gt; parameter (and the &lt;i&gt;TimerCallback&lt;/i&gt; delegate) have an interesting effect on garbage collection: if neither of them reference the System.Threading.Timer object, it may be garbage collected, causing it to stop. This is because both the &lt;i&gt;TimerCallback&lt;/i&gt; delegate and the &lt;i&gt;state&lt;/i&gt; parameter are wrapped into a &lt;b&gt;GCHandle&lt;/b&gt;. If neither of them reference the timer object, it may be eligible for GC, freeing the &lt;b&gt;GCHandle&lt;/b&gt; from its finalizer.&lt;/p&gt;

&lt;p&gt;The single-parameter constructor does not suffer from this problem, because it passes &lt;b&gt;this&lt;/b&gt; for the &lt;i&gt;state&lt;/i&gt; (not &lt;b&gt;null&lt;/b&gt;). Most real-world usage of System.Threading.Timer either references the timer from the callback or uses the timer for the &lt;i&gt;state&lt;/i&gt;, so this interesting garbage collection behavior will probably not be noticed.&lt;/p&gt;

&lt;p&gt;This blog post was prompted by &lt;a href="http://stackoverflow.com/questions/4962172/why-does-a-system-timers-timer-survive-gc-but-not-system-threading-timer"&gt;my own question on Stack Overflow&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7297021906893122222-6342580608716459520?l=nitoprograms.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OlZtT/~4/I-hYrLYPmHM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://nitoprograms.blogspot.com/feeds/6342580608716459520/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://nitoprograms.blogspot.com/2011/07/systemthreadingtimer-constructor-and.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/6342580608716459520?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/6342580608716459520?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OlZtT/~3/I-hYrLYPmHM/systemthreadingtimer-constructor-and.html" title="System.Threading.Timer Constructor and Garbage Collection" /><author><name>Stephen Cleary</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://nitoprograms.blogspot.com/2011/07/systemthreadingtimer-constructor-and.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0cEQHs5eyp7ImA9WhdTFks.&quot;"><id>tag:blogger.com,1999:blog-7297021906893122222.post-8327317883711917999</id><published>2011-07-14T12:30:00.006-04:00</published><updated>2011-07-14T12:30:01.523-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-07-14T12:30:01.523-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Option Parsing" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="Nito.KitchenSink" /><title>Option Parsing: Options with Optional Arguments</title><content type="html">&lt;p&gt;All of the examples so far have illustrated &lt;i&gt;options with required arguments&lt;/i&gt;; that is, if the option is passed, it must be followed by an argument. It's also possible to define an option that takes an optional argument:&lt;/p&gt;

&lt;pre class="brush:csharp"&gt;
class Program
{
  private sealed class Options : OptionArgumentsBase
  {
    [Option("with-extreme-prejudice", 'p', OptionArgument.Optional)]
    public int? PrejudiceLevel { get; set; }
  }

  static int Main()
  {
    try
    {
      var options = OptionParser.Parse&amp;lt;Options&amp;gt;();

      if (options.PrejudiceLevel.HasValue)
        Console.WriteLine("Extreme Prejudice specified: " + options.PrejudiceLevel.Value);
      else
        Console.WriteLine("Regular prejudice will do.");

      return 0;
    }
    catch (OptionParsingException ex)
    {
      Console.Error.WriteLine(ex.Message);
      return 2;
    }
    catch (Exception ex)
    {
      Console.Error.WriteLine(ex);
      return 1;
    }
  }
}
&lt;/pre&gt;

&lt;pre&gt;
&amp;gt; CommandLineParsingTest.exe
Regular prejudice will do.

&amp;gt; CommandLineParsingTest.exe -p 3
Extreme Prejudice specified: 3

&amp;gt; CommandLineParsingTest.exe -p
Regular prejudice will do.
&lt;/pre&gt;

&lt;p&gt;The last example above illustrates the problem with options that take optional arguments: there isn't an easy way to determine whether the option &lt;i&gt;was passed without an argument&lt;/i&gt; or the option &lt;i&gt;was not passed at all&lt;/i&gt;. In both of these cases, the property is left at the default value (&lt;b&gt;null&lt;/b&gt; in this case).&lt;/p&gt;

&lt;p&gt;The solution is to use the &lt;b&gt;OptionPresent&lt;/b&gt; attribute, as such:&lt;/p&gt;

&lt;pre class="brush:csharp"&gt;
class Program
{
  private sealed class Options : OptionArgumentsBase
  {
    [Option("with-extreme-prejudice", 'p', OptionArgument.Optional)]
    public int? PrejudiceLevel { get; set; }

    [OptionPresent('p')]
    public bool PrejudiceLevelWasSpecified { get; set; }
  }

  static int Main()
  {
    try
    {
      var options = OptionParser.Parse&lt;Options&gt;();

      if (!options.PrejudiceLevelWasSpecified)
        Console.WriteLine("Regular prejudice will do.");
      else if (options.PrejudiceLevel.HasValue)
        Console.WriteLine("Extreme Prejudice specified: " + options.PrejudiceLevel.Value);
      else
        Console.WriteLine("Extreme Prejudice specified.");

      return 0;
    }
    catch (OptionParsingException ex)
    {
      Console.Error.WriteLine(ex.Message);
      return 2;
    }
    catch (Exception ex)
    {
      Console.Error.WriteLine(ex);
      return 1;
    }
  }
}
&lt;/pre&gt;

&lt;pre&gt;
&amp;gt; CommandLineParsingTest.exe
Regular prejudice will do.

&amp;gt; CommandLineParsingTest.exe -p 3
Extreme Prejudice specified: 3

&amp;gt; CommandLineParsingTest.exe -p
Extreme Prejudice specified.
&lt;/pre&gt;

&lt;p&gt;It is now possible to distinguish all possibilities. The &lt;b&gt;OptionPresent&lt;/b&gt; example above uses the short option name, but this attribute also works with long names.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7297021906893122222-8327317883711917999?l=nitoprograms.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OlZtT/~4/1Sd1d3laezE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://nitoprograms.blogspot.com/feeds/8327317883711917999/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://nitoprograms.blogspot.com/2011/07/option-parsing-options-with-optional.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/8327317883711917999?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/8327317883711917999?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OlZtT/~3/1Sd1d3laezE/option-parsing-options-with-optional.html" title="Option Parsing: Options with Optional Arguments" /><author><name>Stephen Cleary</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://nitoprograms.blogspot.com/2011/07/option-parsing-options-with-optional.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEUEQXsyfSp7ImA9WhdTEEg.&quot;"><id>tag:blogger.com,1999:blog-7297021906893122222.post-3453165979776023539</id><published>2011-07-07T12:30:00.006-04:00</published><updated>2011-07-07T12:30:00.595-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-07-07T12:30:00.595-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Option Parsing" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="Nito.KitchenSink" /><title>Option Parsing: Default and Nullable Argument Values</title><content type="html">&lt;p&gt;Most of our examples so far have already dealt with options taking arguments, because most options in the real world &lt;i&gt;do&lt;/i&gt; take arguments. Today we'll start looking at option arguments in depth.&lt;/p&gt;

&lt;p&gt;The &lt;a href="http://nitoprograms.blogspot.com/2011/06/option-parsing-option-parsing-pipeline.html"&gt;option pipeline&lt;/a&gt; post laid out the steps taken when using an Option Arguments class:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The Option Arguments class is default-constructed.&lt;/li&gt;
&lt;li&gt;Attributes of properties on the class are used to produce a collection of option definitions.&lt;/li&gt;
&lt;li&gt;The command line is parsed, setting properties on the Option Arguments instance.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We'll take advantage of these steps to handle several common scenarios.&lt;/p&gt;

&lt;h4&gt;Default Values&lt;/h4&gt;

&lt;p&gt;Default argument values are set in the default constructor:&lt;/p&gt;

&lt;pre class="brush:csharp"&gt;
class Program
{
  private sealed class Options : OptionArgumentsBase
  {
    public Options()
    {
      // Set default values.
      Quality = 3;
    }

    [Option("level", 'l')]
    public int Level { get; set; }

    [Option("quality")]
    public int Quality { get; set; }
  }

  static int Main()
  {
    try
    {
      var options = OptionParser.Parse&amp;lt;Options&amp;gt;();

      Console.WriteLine("Level: " + options.Level);
      Console.WriteLine("Quality: " + options.Quality);

      return 0;
    }
    catch (OptionParsingException ex)
    {
      Console.Error.WriteLine(ex.Message);
      return 2;
    }
    catch (Exception ex)
    {
      Console.Error.WriteLine(ex);
      return 1;
    }
  }
}
&lt;/pre&gt;

&lt;pre&gt;
&amp;gt; CommandLineParsingTest.exe
Level: 0
Quality: 3

&amp;gt; CommandLineParsingTest.exe /level 7
Level: 7
Quality: 3

&amp;gt; CommandLineParsingTest.exe /quality 4
Level: 0
Quality: 4
&lt;/pre&gt;

&lt;h4&gt;Nullable Values&lt;/h4&gt;

&lt;p&gt;There are some situations where a "default value" doesn't make sense for an option; you need to know whether there was a value passed, and what the value is (if it was passed). In this situation, you can use a nullable value type for your property:&lt;/p&gt;

&lt;pre class="brush:csharp"&gt;
class Program
{
  private sealed class Options : OptionArgumentsBase
  {
    [Option("level", 'l')]
    public int? Level { get; set; }

    [Option("name", 'n')]
    public string Name { get; set; }
  }

  static int Main()
  {
    try
    {
      var options = OptionParser.Parse&amp;lt;Options&amp;gt;();

      if (options.Level.HasValue)
        Console.WriteLine("Level: " + options.Level.Value);
      else
        Console.WriteLine("Level not specified.");
      if (options.Name != null)
        Console.WriteLine("Name: " + options.Name);
      else
        Console.WriteLine("Name not specified.");

      return 0;
    }
    catch (OptionParsingException ex)
    {
      Console.Error.WriteLine(ex.Message);
      return 2;
    }
    catch (Exception ex)
    {
      Console.Error.WriteLine(ex);
      return 1;
    }
  }
}
&lt;/pre&gt;

&lt;pre&gt;
&amp;gt; CommandLineParsingTest.exe
Level not specified.
Name not specified.

&amp;gt; CommandLineParsingTest.exe /level 3
Level: 3
Name not specified.

&amp;gt; CommandLineParsingTest.exe /level 0
Level: 0
Name not specified.

&amp;gt; CommandLineParsingTest.exe /name Bob
Level not specified.
Name: Bob

&amp;gt; CommandLineParsingTest.exe /name ""
Level not specified.
Name: 
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7297021906893122222-3453165979776023539?l=nitoprograms.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OlZtT/~4/w5Ba-Y1a8LY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://nitoprograms.blogspot.com/feeds/3453165979776023539/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://nitoprograms.blogspot.com/2011/07/option-parsing-default-and-nullable.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/3453165979776023539?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/3453165979776023539?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OlZtT/~3/w5Ba-Y1a8LY/option-parsing-default-and-nullable.html" title="Option Parsing: Default and Nullable Argument Values" /><author><name>Stephen Cleary</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://nitoprograms.blogspot.com/2011/07/option-parsing-default-and-nullable.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0MEQ387fyp7ImA9WhZaFEg.&quot;"><id>tag:blogger.com,1999:blog-7297021906893122222.post-1297021806070842577</id><published>2011-06-30T12:30:00.008-04:00</published><updated>2011-06-30T12:30:02.107-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-30T12:30:02.107-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Option Parsing" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="Nito.KitchenSink" /><title>Option Parsing: Option Names</title><content type="html">&lt;p&gt;An option may have a long name, a short name, or both. "Short names" are just single characters, while "long names" are strings. Option names may not contain the special characters &lt;b&gt;:&lt;/b&gt; or &lt;b&gt;=&lt;/b&gt;.&lt;/p&gt;

&lt;p&gt;Commonly-used options should have both a long name and a short name. The short name enables faster typing on the command line, while the long name enables self-documenting command lines (for use in script and batch files). Normally, the short name is the first character of the long name, but this is not required.&lt;/p&gt;

&lt;p&gt;Less-common options should have just a long name; this avoids polluting the short name namespace.&lt;/p&gt;

&lt;pre class="brush:csharp"&gt;
using System;
using Nito.KitchenSink.OptionParsing;

class Program
{
  private sealed class Options : OptionArgumentsBase
  {
    [Option("level", 'l')]
    public int Level { get; set; }

    [Option("priority")]
    public int Priority { get; set; }
  }

  static int Main()
  {
    try
    {
      var options = OptionParser.Parse&amp;lt;Options&amp;gt;();
      
      Console.WriteLine("Level: " + options.Level);
      Console.WriteLine("Priority: " + options.Priority);

      return 0;
    }
    catch (OptionParsingException ex)
    {
      Console.Error.WriteLine(ex.Message);
      return 2;
    }
    catch (Exception ex)
    {
      Console.Error.WriteLine(ex);
      return 1;
    }
  }
}
&lt;/pre&gt;

&lt;pre&gt;
&amp;gt; CommandLineParsingTest.exe
Level: 0
Priority: 0

&amp;gt; CommandLineParsingTest.exe /l 3
Level: 3
Priority: 0

&amp;gt; CommandLineParsingTest.exe /level 3
Level: 3
Priority: 0

&amp;gt; CommandLineParsingTest.exe /priority 1
Level: 0
Priority: 1

&amp;gt; CommandLineParsingTest.exe /p 1
Unknown option  p  in parameter  /p
&lt;/pre&gt;

&lt;p&gt;Normally, options do not have just a short name without a long name, but you &lt;i&gt;can&lt;/i&gt; do it if you want do.&lt;/p&gt;

&lt;h4&gt;Multiple Long and Short Names&lt;/h4&gt;

&lt;p&gt;Options may have "aliases" (multiple long and/or short names). The easiest way to add aliases is to have separate properties on your Option Arguments class that refer to the same underlying field.&lt;/p&gt;

&lt;p&gt;The following example shows one alias that is used to change an old option "level" into a more descriptive option "frob-level", marking the old option as obsolete. Another alias "frobbing-level" is also added, which is just a regular alias (without any options marked obsolete).&lt;/p&gt;

&lt;pre class="brush:csharp"&gt;
class Program
{
  private sealed class Options : OptionArgumentsBase
  {
    // The old "level" option, now obsolete and made into an alias for "frob-level".
    [Option("level", 'l')]
    [Obsolete]
    public int Level
    {
      get { return FrobLevel; }
      set
      {
        Console.Error.WriteLine("Warning: The --level option is obsolete; use --frob-level instead.");
        FrobLevel = value;
      }
    }

    [Option("frob-level")]
    public int FrobLevel { get; set; }

    // Another alias for "frob-level"; this one is not obsolete.
    [Option("frobbing-level")]
    public int FrobbingLevel
    {
      get { return FrobLevel; }
      set { FrobLevel = value; }
    }
  }

  static int Main()
  {
    try
    {
      var options = OptionParser.Parse&amp;lt;Options&amp;gt;();

      Console.WriteLine(options.FrobLevel);

      return 0;
    }
    catch (OptionParsingException ex)
    {
      Console.Error.WriteLine(ex.Message);
      return 2;
    }
    catch (Exception ex)
    {
      Console.Error.WriteLine(ex);
      return 1;
    }
  }
}
&lt;/pre&gt;

&lt;pre&gt;
&amp;gt; CommandLineParsingTest.exe /level 4
Warning: The --level option is obsolete; use --frob-level instead.
4

&amp;gt; CommandLineParsingTest.exe /frob-level 4
4

&amp;gt; CommandLineParsingTest.exe /frobbing-level 6
6
&lt;/pre&gt;

&lt;h4&gt;Abbreviated Option Names&lt;/h4&gt;

&lt;p&gt;Some programs support abbreviated option names; for example, the option "pack" may be abbreviated as "pa" or "p" (assuming there is no other option that starts with "pa" or "p", respectively). However, this causes backwards compatibility issues; for example, an updated version of the program may introduce an option named "push", and any scripts that used the abbreviated option "p" then become ambiguous. For this reason, &lt;a href="http://www.nuget.org/List/Packages/Nito.KitchenSink.OptionParsing"&gt;Nito.KitchenSink.OptionParsing&lt;/a&gt; does not include automatic support for abbreviated option names. If you need abbreviated option names, you may use explicit aliases to achieve the same effect.&lt;/p&gt;

&lt;pre&gt;
&amp;gt; CommandLineParsingTest.exe /frob 6
Unknown option  frob  in parameter  /frob
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7297021906893122222-1297021806070842577?l=nitoprograms.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OlZtT/~4/54m-1oHUhds" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://nitoprograms.blogspot.com/feeds/1297021806070842577/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://nitoprograms.blogspot.com/2011/06/option-parsing-option-names.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/1297021806070842577?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/1297021806070842577?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OlZtT/~3/54m-1oHUhds/option-parsing-option-names.html" title="Option Parsing: Option Names" /><author><name>Stephen Cleary</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://nitoprograms.blogspot.com/2011/06/option-parsing-option-names.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEEEQ389cSp7ImA9WhZbGEk.&quot;"><id>tag:blogger.com,1999:blog-7297021906893122222.post-8857663109918908825</id><published>2011-06-23T12:30:00.009-04:00</published><updated>2011-06-23T12:30:02.169-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-23T12:30:02.169-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Option Parsing" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="Nito.KitchenSink" /><title>Option Parsing: Error Handling</title><content type="html">&lt;p&gt;The &lt;a href="http://www.nuget.org/List/Packages/Nito.KitchenSink.OptionParsing"&gt;Nito.KitchenSink Option Parsing Library&lt;/a&gt; wraps all option parsing errors into an exception derived from &lt;b&gt;Nito.KitchenSink.OptionParsing.OptionParsingException&lt;/b&gt;. There are three more specific exception types (&lt;b&gt;InvalidParameterException&lt;/b&gt;, &lt;b&gt;OptionArgumentException&lt;/b&gt;, and &lt;b&gt;UnknownOptionException&lt;/b&gt;), but they are seldomly needed.&lt;/p&gt;

&lt;p&gt;All steps of the option parsing pipeline should only throw exceptions derived from &lt;b&gt;OptionParsingException&lt;/b&gt;. In particular, this is true for custom validation (which will be described in detail in a future post).&lt;/p&gt;

&lt;p&gt;The following example program shows how option parsing errors should be handled in a console application:&lt;/p&gt;

&lt;pre class="brush:csharp"&gt;
using System;
using Nito.KitchenSink.OptionParsing;

class Program
{
  private sealed class Options : OptionArgumentsBase
  {
    [Option("level", 'l')]
    public int Level { get; set; }

    public static int Usage()
    {
      // Standard console size:
      //                      [                                                                                ]
      Console.Error.WriteLine("Usage: CommandLineOptionTest &amp;lt;arguments&amp;gt;");
      Console.Error.WriteLine("  -l, --level=LEVEL        level at which to operate");
      return 2;
    }
  }

  static int Main()
  {
    try
    {
      var options = OptionParser.Parse&amp;lt;Options&amp;gt;();
      
      // Program logic
      Console.WriteLine(options.Level);

      return 0;
    }
    catch (OptionParsingException ex)
    {
      Console.Error.WriteLine(ex.Message);
      return Options.Usage();
    }
    catch (Exception ex)
    {
      Console.Error.WriteLine(ex);
      return 1;
    }
  }
}
&lt;/pre&gt;

&lt;p&gt;First, the &lt;b&gt;Options&lt;/b&gt; class is declared, which defines the options our program takes. It also exposes a &lt;b&gt;Usage&lt;/b&gt; method, which displays command-line usage information. &lt;b&gt;Usage&lt;/b&gt; writes its information to &lt;b&gt;Console.Error&lt;/b&gt; and returns an error code.&lt;/p&gt;

&lt;blockquote&gt;The Nito.KitchenSink.OptionParsing library does not attempt to write the &lt;b&gt;Usage&lt;/b&gt; method for you automatically. Other option parsing libraries have attempted this, but the results are (IMHO) less than ideal.&lt;/blockquote&gt;

&lt;p&gt;The program's &lt;b&gt;Main&lt;/b&gt; method returns an &lt;b&gt;int&lt;/b&gt;, and contains a top-level try/catch. The try block parses the options, performs its requested task (in this case, the program just writes the Level option to the console), and then returns 0 (meaning "success").&lt;/p&gt;

&lt;p&gt;If there is an option parsing exception, then the exception message is written to &lt;b&gt;Console.Error&lt;/b&gt;, usage information is displayed, and an error code is returned.&lt;/p&gt;

&lt;p&gt;If there is some other (unexpected) exception (during option parsing or program logic), then the entire exception (including the call stack) is written to &lt;b&gt;Console.Error&lt;/b&gt; and an error code is returned.&lt;/p&gt;

&lt;h4&gt;Notes&lt;/h4&gt;

&lt;p&gt;For console programs, a return value of 0 indicates success and any other return value usually indicates an error. I used two different error codes in the example above, but they could just as easily be a single error code because distinguishing usage errors is not normally useful.&lt;/p&gt;

&lt;p&gt;An options class does not have to include a &lt;b&gt;Usage&lt;/b&gt; method; I just usually put it there so it's along with the class that defines the options. In future blog posts, I'll post example code that skips the &lt;b&gt;Usage&lt;/b&gt; method to avoid distractions, but it should be included in real-world code.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7297021906893122222-8857663109918908825?l=nitoprograms.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OlZtT/~4/UYxlXGXKe_Q" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://nitoprograms.blogspot.com/feeds/8857663109918908825/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://nitoprograms.blogspot.com/2011/06/option-parsing-error-handling.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/8857663109918908825?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/8857663109918908825?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OlZtT/~3/UYxlXGXKe_Q/option-parsing-error-handling.html" title="Option Parsing: Error Handling" /><author><name>Stephen Cleary</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://nitoprograms.blogspot.com/2011/06/option-parsing-error-handling.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C08EQXs6eip7ImA9WhZbEkk.&quot;"><id>tag:blogger.com,1999:blog-7297021906893122222.post-5517804048510696948</id><published>2011-06-16T12:30:00.018-04:00</published><updated>2011-06-16T12:30:00.512-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-16T12:30:00.512-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Option Parsing" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="Nito.KitchenSink" /><title>Option Parsing: Lexing</title><content type="html">&lt;p&gt;The first step in parsing a command line is &lt;i&gt;lexing&lt;/i&gt;, which converts a single string (the command line) into a sequence of strings (individual options and/or arguments). Actually, the &lt;i&gt;very&lt;/i&gt; first step takes place before the program even runs: the command shell has its own simple lexer.&lt;/p&gt;

&lt;h4&gt;Command Shell Escaping and Quoting&lt;/h4&gt;

&lt;blockquote&gt;The information in this section is derived from the TechNet articles &lt;a href="http://technet.microsoft.com/en-us/library/bb490954.aspx"&gt;Command shell overview&lt;/a&gt; (&lt;a href="http://www.webcitation.org/5ytzcAcrB"&gt;webcite&lt;/a&gt;) and &lt;a href="http://technet.microsoft.com/en-us/library/cc723564.aspx"&gt;The Windows NT Command Shell&lt;/a&gt; (&lt;a href="http://www.webcitation.org/5ytzuqd4h"&gt;webcite&lt;/a&gt;).&lt;/blockquote&gt;

&lt;p&gt;The command shell has these special characters: &lt;b&gt;&amp;&lt;/b&gt;, &lt;b&gt;|&lt;/b&gt;, &lt;b&gt;(&lt;/b&gt;, &lt;b&gt;)&lt;/b&gt;, &lt;b&gt;&amp;lt;&lt;/b&gt;, &lt;b&gt;&amp;gt;&lt;/b&gt;, and &lt;b&gt;^&lt;/b&gt;. There are two ways to pass these special characters on the command line: &lt;i&gt;escaping&lt;/i&gt; and &lt;i&gt;quoting&lt;/i&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;b&gt;^&lt;/b&gt; character is the shell escape character. You may prefix any of the special shell characters with that escape character, and the special shell character will be passed to the program (without the escape character).&lt;/p&gt;

&lt;p&gt;The command shell also supports quoting; special characters may be passed within a pair of double-quotes. In this case, the special characters are passed to the program along with the surrounding quotes.&lt;/p&gt;

&lt;p&gt;The shell escaping and quoting appears to be a simple algorithm: escaped characters (including normal characters) are passed through directly, and each (non-escaped) double-quote either starts or ends a quoted string. Consider the outputs from this example program:&lt;/p&gt;

&lt;pre class="brush:csharp"&gt;
static void Main(string[] args)
{
  Console.WriteLine(Environment.CommandLine);
}
&lt;/pre&gt;

&lt;pre&gt;
&amp;gt; CommandLineParsingTest.exe ^^ "^"
CommandLineParsingTest.exe ^ "^"

&amp;gt; CommandLineParsingTest.exe ^"^"
CommandLineParsingTest.exe ""

&amp;gt; CommandLineParsingTest.exe ^""
CommandLineParsingTest.exe ""

&amp;gt; CommandLineParsingTest.exe "^"^"
CommandLineParsingTest.exe "^""

&amp;gt; CommandLineParsingTest.exe "^"^^"
CommandLineParsingTest.exe "^"^"

&amp;gt; CommandLineParsingTest.exe "^^
CommandLineParsingTest.exe "^^
&lt;/pre&gt;

&lt;p&gt;Shell escaping and quoting are applied to every process by the Command Shell; there is no way to opt out of this behavior. After the command shell does its own escaping and quoting, the command line is passed to the program.&lt;/p&gt;

&lt;h4&gt;Default .NET Lexing&lt;/h4&gt;

&lt;p&gt;The command line is split up into a list of process arguments by the .NET runtime. The algorithm is described in the documentation for &lt;a href="http://msdn.microsoft.com/en-us/library/system.environment.getcommandlineargs.aspx"&gt;Environment.GetCommandLineArgs&lt;/a&gt;. The same results (except for the process name) are also passed as the single argument to the &lt;b&gt;Main&lt;/b&gt; method, if present.&lt;/p&gt;

&lt;p&gt;The .NET lexing also uses a combination of escaping and quoting, but it has some surprising results because escaping is allowed inside quoting. The escape character is &lt;b&gt;\&lt;/b&gt;, and the quote character is the double-quote.&lt;/p&gt;

&lt;p&gt;Each non-escaped double-quote starts or ends a quoted string, just like command shell quoting. However, unlike command shell quoting, escaping is allowed within quoted strings. The .NET lexing also allows two consecutive double-quotes inside a quoted string to represent a single double-quote. Consider the outputs from this example program:&lt;/p&gt;

&lt;pre class="brush:csharp"&gt;
static void Main(string[] args)
{
  foreach (var arg in args)
    Console.WriteLine(arg);
}
&lt;/pre&gt;

&lt;pre&gt;
&amp;gt; CommandLineParsingTest.exe "a"
a

&amp;gt; CommandLineParsingTest.exe \"a"
"a

&amp;gt; CommandLineParsingTest.exe \"a
"a

&amp;gt; CommandLineParsingTest.exe "a\"
a"

&amp;gt; CommandLineParsingTest.exe "a\\"
a\

&amp;gt; CommandLineParsingTest.exe a \"
a
"

&amp;gt; CommandLineParsingTest.exe "a \\"
a \

&amp;gt; CommandLineParsingTest.exe "a\"b"
a"b

&amp;gt; CommandLineParsingTest.exe "a""b"
a"b

&amp;gt; CommandLineParsingTest.exe a "" """"
a

"
&lt;/pre&gt;

&lt;p&gt;This lexing behavior is particularly problematic when passing directories. Since directories may contain spaces, they should be wrapped with quotes. However, if the directory ends with a backslash, the closing quote will be escaped:&lt;/p&gt;

&lt;pre&gt;
&amp;gt; CommandLineParsingTest.exe "c:\my path"
c:\my path

&amp;gt; CommandLineParsingTest.exe "c:\my path\"
c:\my path"
&lt;/pre&gt;

&lt;p&gt;This is a rather serious limitation of the default .NET lexer. It is possible to write your own replacement lexer using a different algorithm. This lexer would take the process command line as input and produce a sequence of strings.&lt;/p&gt;

&lt;p&gt;The &lt;a href="http://nuget.org/List/Packages/Nito.KitchenSink.OptionParsing"&gt;Nito.KitchenSink.OptionParser&lt;/a&gt; library does not have a lexer of its own, but it will accept a sequence of strings as input into its parsing methods. If no sequence of strings is passed to a parsing method, then the method will use the process' command line lexed with the default .NET lexer.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7297021906893122222-5517804048510696948?l=nitoprograms.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OlZtT/~4/WUeBW8zMLIc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://nitoprograms.blogspot.com/feeds/5517804048510696948/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://nitoprograms.blogspot.com/2011/06/option-parsing-lexing.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/5517804048510696948?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/5517804048510696948?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OlZtT/~3/WUeBW8zMLIc/option-parsing-lexing.html" title="Option Parsing: Lexing" /><author><name>Stephen Cleary</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://nitoprograms.blogspot.com/2011/06/option-parsing-lexing.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUcEQH4_fyp7ImA9WhZUFk4.&quot;"><id>tag:blogger.com,1999:blog-7297021906893122222.post-6204935143075600923</id><published>2011-06-09T12:30:00.000-04:00</published><updated>2011-06-09T12:30:01.047-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-09T12:30:01.047-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Option Parsing" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="Nito.KitchenSink" /><title>Option Parsing: The Option Parsing Pipeline</title><content type="html">&lt;p&gt;There are three main phases during option parsing:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Lexing&lt;/li&gt;
&lt;li&gt;Parsing&lt;/li&gt;
&lt;li&gt;Validation&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The &lt;b&gt;Lexing&lt;/b&gt; phase deals with the escaping and quoting of special characters and splitting the command line string into a sequence of strings. The &lt;b&gt;Parsing&lt;/b&gt; phase evaluates the sequence of strings from the lexing phase, and interprets them as options and arguments; this includes parsing arguments as necessary, e.g., converting a string argument &lt;i&gt;"3"&lt;/i&gt; into the numeric argument value &lt;i&gt;3&lt;/i&gt;. The &lt;b&gt;Validation&lt;/b&gt; phase determines if the options and arguments represent a valid command for the program to perform.&lt;/p&gt;

&lt;p&gt;The &lt;a href="http://nuget.org/List/Packages/Nito.KitchenSink.OptionParsing"&gt;Nito.KitchenSink.OptionParser&lt;/a&gt; library does not have a &lt;i&gt;lexer&lt;/i&gt;, but does have a &lt;i&gt;parser&lt;/i&gt; and hooks for &lt;i&gt;validation&lt;/i&gt;. The easiest way to use the library is by calling a single method:&lt;/p&gt;

&lt;pre class="brush:csharp"&gt;
var options = OptionParser.Parse&amp;lt;MyOptionArguments&amp;gt;();
&lt;/pre&gt;

&lt;p&gt;This single method wraps all the phases of the option parsing pipeline:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The command line for the process is lexed using the default .NET lexing.&lt;/li&gt;
&lt;li&gt;The option and argument definitions are inferred from properties and attributes on the &lt;b&gt;MyOptionArguments&lt;/b&gt; type.&lt;/li&gt;
&lt;li&gt;These definitions are used to parse the lexed command line, saving the results into properties on a default-constructed &lt;b&gt;MyOptionsArguments&lt;/b&gt; object.&lt;/li&gt;
&lt;li&gt;Validation is performed on the &lt;b&gt;MyOptionsArguments&lt;/b&gt; object, which is then returned.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Future posts will show how each of these steps may be configured (or replaced).&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7297021906893122222-6204935143075600923?l=nitoprograms.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OlZtT/~4/PY-ZRL3dgkE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://nitoprograms.blogspot.com/feeds/6204935143075600923/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://nitoprograms.blogspot.com/2011/06/option-parsing-option-parsing-pipeline.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/6204935143075600923?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/6204935143075600923?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OlZtT/~3/PY-ZRL3dgkE/option-parsing-option-parsing-pipeline.html" title="Option Parsing: The Option Parsing Pipeline" /><author><name>Stephen Cleary</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://nitoprograms.blogspot.com/2011/06/option-parsing-option-parsing-pipeline.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEYGQ384cSp7ImA9WhdXEEs.&quot;"><id>tag:blogger.com,1999:blog-7297021906893122222.post-1832065908503459147</id><published>2011-06-02T12:30:00.001-04:00</published><updated>2011-08-22T22:22:02.139-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-22T22:22:02.139-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Windows Services" /><category scheme="http://www.blogger.com/atom/ns#" term="Windows" /><title>How to Run Processes Remotely</title><content type="html">&lt;p&gt;Today I'm going to delve deeply into something I discovered many years ago (c. 2003). It's an interesting little trick that hopefully no one will ever have to use.&lt;/p&gt;

&lt;p&gt;When a process running on one computer needs to perform some operation on &lt;i&gt;another&lt;/i&gt; computer, the common solution is to actually have two processes that use interprocess communication. The one process sends its commands to the other process, which executes them on behalf of the first process. Normally, one must install a server on one computer and a client on the other. So, if someone needs to perform an operation on another computer, then that computer must &lt;i&gt;already have&lt;/i&gt; the software installed.&lt;/p&gt;

&lt;p&gt;However, there &lt;i&gt;is&lt;/i&gt; a way to send a program to a remote computer and run it, without having any special existing software on the target machine. This approach doesn't work in every situation, but it's useful to know. The command line programs in the famous &lt;a href="http://technet.microsoft.com/en-us/sysinternals/bb896649"&gt;PSTools suite&lt;/a&gt; use the approach documented here to "inject" copies of themselves onto remote computers; this allows a simple form of remote administration. The white paper &lt;a href="http://www.ntkernel.com/w&amp;p.php?id=15"&gt;PsExec Internals&lt;/a&gt; (&lt;a href="http://www.webcitation.org/5yUALT8gw"&gt;webcite&lt;/a&gt;) includes the specific details for PsExec.&lt;/p&gt;

&lt;h4&gt;Step 1: Establish an Authenticated Connection&lt;/h4&gt;

&lt;h5&gt;About Connections&lt;/h5&gt;

&lt;p&gt;A user session on one computer may have network connections to other computers. One common example is network drives; each network drive is a connection to another computer. Network connections may also exist without mapping a drive letter.&lt;/p&gt;

&lt;blockquote&gt;Network connections may be examined and modified using the &lt;a href="http://msdn.microsoft.com/en-us/library/aa385406.aspx"&gt;Windows Networking (WNet) API&lt;/a&gt; or the &lt;b&gt;net&lt;/b&gt; command. Unfortunately, there are no .NET wrappers for this API in the BCL.&lt;/blockquote&gt;

&lt;h5&gt;About Authentication&lt;/h5&gt;

&lt;p&gt;Each network connection has to be authenticated, but there are situations where this happens automatically. When you map a network drive using Explorer, by default Windows will use your local logon to attempt to log onto the remote machine, and if it's accepted, you won't actually get prompted for credentials. This is particularly common in Domain environments.&lt;/p&gt;

&lt;blockquote&gt;The &lt;b&gt;net use&lt;/b&gt; command allows you to display current connections to other computers, and add or remove those connections.&lt;/blockquote&gt;

&lt;h5&gt;Authentication Quirks&lt;/h5&gt;

&lt;p&gt;Microsoft made the design decision that any number of network connections may exist between two different computers, but that the same credentials must be used for all those connections. You may use different credentials for connections to two different servers, but all connections to the same server must use the same credentials. According to a rather dated &lt;a href="http://support.microsoft.com/kb/106211"&gt;KB106211&lt;/a&gt; (&lt;a href="http://www.webcitation.org/5yelY3I5Z"&gt;webcite&lt;/a&gt;), this is done "for security purposes." The newer &lt;a href="http://support.microsoft.com/kb/183366"&gt;KB183366&lt;/a&gt; (&lt;a href="http://www.webcitation.org/5yemC7rC8"&gt;webcite&lt;/a&gt;) documents the limitation in more detail, but does not give a reason.&lt;/p&gt;

&lt;p&gt;If you do attempt to use different credentials for different connections to the same server, you'll get a 1219 error: "Multiple connections to a server or shared resource by the same user, using more than one user name, are not allowed. Disconnect all previous connections to the server or shared resource and try again." I've also seen this error when Explorer tries to auto-reconnect its mapped drives and it gets confused; it appears to happen more commonly on wireless networks when resuming from a low-power state.&lt;/p&gt;

&lt;blockquote&gt;There's a "greybeard" trick used to get around this limitation: connect to the IP address instead of the hostname (or, if you want more work, set up multiple hostnames for that server). The logic behind "the same server" appears to be just a string comparison. This workaround has been documented in &lt;a href="http://support.microsoft.com/kb/938120"&gt;KB938120&lt;/a&gt; (&lt;a href="http://www.webcitation.org/5yemWypLb"&gt;webcite&lt;/a&gt;).&lt;/blockquote&gt;

&lt;p&gt;There are some notable situations where it's not possible to establish an authenticated connection:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If the target (server) machine is running a client OS "Home" edition (e.g., XP Home, Vista Home Basic, Vista Home Premium, Windows 7 Home Basic, Windows 7 Home Premium), then no authenticated connections are possible.&lt;/li&gt;
&lt;li&gt;If the target (server) machine is running a client OS "Professional" edition (e.g., XP Professional, Vista Business/Enterprise/Ultimate, Windows 7 Professional/Enterprise/Ultimate), then that machine must &lt;i&gt;either&lt;/i&gt; be a member of a domain &lt;i&gt;or&lt;/i&gt; turn off "simple file sharing" to support authenticated connections.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note that if you're working in a domain enviroment, Everything Just Works. For the rest of us, we have to turn off "simple file sharing."&lt;/p&gt;

&lt;p&gt;If the server is running a Home edition, or if it is not connected to a domain and is using simple file sharing, then it does not support authenticated connections. Instead, every incoming network connection is authenticated with the Guest account; see &lt;a href="http://support.microsoft.com/kb/300489"&gt;KB300489&lt;/a&gt; (&lt;a href="http://www.webcitation.org/5yenW0M9U"&gt;webcite&lt;/a&gt;).&lt;/p&gt;

&lt;blockquote&gt;Another non-authenticated approach is to use &lt;i&gt;null sessions&lt;/i&gt;, which are truly anonymous. This means they work even if the Guest account is disabled. Null sessions are disabled by default and considered a security risk.&lt;/blockquote&gt;

&lt;p&gt;To send a program to a remote computer, you'll need an authenticated connection. A Guest authentication (or null session) is insufficient.&lt;/p&gt;

&lt;h5&gt;Common Shares&lt;/h5&gt;

&lt;p&gt;There are some hidden network shares for Windows systems. They are recreated automatically on reboot if they've been deleted.&lt;/p&gt;

&lt;blockquote&gt;Hidden shares are not shown in the normal GUI, but they can be displayed by the command &lt;b&gt;net share&lt;/b&gt;.&lt;/blockquote&gt;

&lt;p&gt;The standard hidden share names that are important to us are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;IPC$&lt;/b&gt; - An share that is used only for authentication.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;ADMIN$&lt;/b&gt; - The equivalent of &lt;b&gt;%SYSTEMROOT%&lt;/b&gt; (usually "C:\Windows").&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;You can create your own hidden shares: &lt;a href="http://support.microsoft.com/kb/314984"&gt;KB314984&lt;/a&gt; (&lt;a href="http://www.webcitation.org/5yep2mpjH"&gt;webcite&lt;/a&gt;). You can also prevent the automatic creation of the standard hidden shares: &lt;a href="http://support.microsoft.com/kb/954422"&gt;KB954422&lt;/a&gt; (&lt;a href="http://www.webcitation.org/5yep4SjDH"&gt;webcite&lt;/a&gt;), but this may cause lots of problems: &lt;a href="http://support.microsoft.com/kb/842715"&gt;KB842715&lt;/a&gt; (&lt;a href="http://www.webcitation.org/5yepDm7Rl"&gt;webcite&lt;/a&gt;).&lt;/blockquote&gt;

&lt;p&gt;With all of that background information, our first step is to actually establish the authenticated connection to &lt;b&gt;\\computer\IPC$&lt;/b&gt;. The other steps are quite simple in comparison!&lt;/p&gt;

&lt;h4&gt;Step 2: Copy the Program to the Target&lt;/h4&gt;

&lt;p&gt;Just copy the program to &lt;b&gt;\\computer\ADMIN$&lt;/b&gt;, right into the Windows directory. I recommend renaming the file during the copy to a unique name, to avoid conflicts. You don't need to explicitly establish a network connection to &lt;b&gt;\\computer\ADMIN$&lt;/b&gt;; the existing connection to &lt;b&gt;\\computer\IPC$&lt;/b&gt; will be your authentication.&lt;/p&gt;

&lt;h4&gt;Step 3: Register and Execute the Program&lt;/h4&gt;

&lt;p&gt;This step makes use of the little-known fact that Win32 services may be &lt;i&gt;installed&lt;/i&gt; remotely. The &lt;a href="http://msdn.microsoft.com/en-us/library/ms685148(v=VS.85).aspx"&gt;service configuration API&lt;/a&gt; can be used to install the service on the remote computer and then start it.&lt;/p&gt;

&lt;blockquote&gt;The .NET &lt;a href="http://msdn.microsoft.com/en-us/library/system.serviceprocess.servicecontroller.aspx"&gt;ServiceController class&lt;/a&gt; does expose remote &lt;i&gt;control&lt;/i&gt; of services (starting, stopping, etc), but it does not expose remote &lt;i&gt;installation&lt;/i&gt; of services.&lt;/blockquote&gt;

&lt;h4&gt;Step 4: Securely Communicate&lt;/h4&gt;

&lt;p&gt;Once the service is running on the remote computer, it is simple matter to communicate with the original process and carry out its instructions. It's not quite as simple to do so in a secure manner, though; strongly consider &lt;i&gt;encrypting&lt;/i&gt; all network communication and using &lt;i&gt;impersonation&lt;/i&gt; in the service.&lt;/p&gt;

&lt;blockquote&gt;Also remember that - as a service - you &lt;a href="http://nitoprograms.blogspot.com/search/label/Windows%20Services"&gt;are limited&lt;/a&gt; in what you can do.&lt;/blockquote&gt;

&lt;h4&gt;Enjoy!&lt;/h4&gt;

&lt;p&gt;There aren't too many good use cases for this technique. Remote administration is one, as demonstrated by the PsTools suite from Microsoft TechNet Systems Internals.&lt;/p&gt;

&lt;p&gt;Another possible application is to inject an installer for remote control software, such as VNC or pcAnywhere. This could be useful in the rare case where a computer is physically inaccessible.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7297021906893122222-1832065908503459147?l=nitoprograms.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OlZtT/~4/1BhApJ1bjEA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://nitoprograms.blogspot.com/feeds/1832065908503459147/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://nitoprograms.blogspot.com/2011/06/how-to-run-processes-remotely.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/1832065908503459147?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/1832065908503459147?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OlZtT/~3/1BhApJ1bjEA/how-to-run-processes-remotely.html" title="How to Run Processes Remotely" /><author><name>Stephen Cleary</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://nitoprograms.blogspot.com/2011/06/how-to-run-processes-remotely.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUMEQH0yfyp7ImA9WhZVFE8.&quot;"><id>tag:blogger.com,1999:blog-7297021906893122222.post-8258839092889204805</id><published>2011-05-26T12:30:00.000-04:00</published><updated>2011-05-26T12:30:01.397-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-26T12:30:01.397-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="Sample code" /><category scheme="http://www.blogger.com/atom/ns#" term="Linq" /><title>Getting the ObjectContext from an EntityObject</title><content type="html">&lt;p&gt;There are a few situations where it's useful to get an &lt;b&gt;ObjectContext&lt;/b&gt; from an &lt;b&gt;EntityObject&lt;/b&gt;. Note that in general I do not recommend a design that depends on this; there doesn't appear to be an easy way to do this using code first in EF 4.1 (using the &lt;b&gt;DbContext&lt;/b&gt; API). That said, either of the solutions in this blog post will work when using the &lt;b&gt;ObjectContext&lt;/b&gt; API.&lt;/p&gt;

&lt;p&gt;The most common solution for this problem is from &lt;a href="http://blogs.msdn.com/b/alexj/archive/2009/06/08/tip-24-how-to-get-the-objectcontext-from-an-entity.aspx"&gt;a 2009 Microsoft blog post by Alex James&lt;/a&gt; (&lt;a href="http://www.webcitation.org/5yYYB64NN"&gt;webcite&lt;/a&gt;). Unfortunately, that solution has several limitations (including the requirement that the entities must have relations to other entities). Both of the solutions below do not have these limitations.&lt;/p&gt;

&lt;p&gt;We use an example entity container named &lt;b&gt;NorthwindEntites&lt;/b&gt;, derived from &lt;b&gt;ObjectContext&lt;/b&gt;. To this we will add a factory method &lt;b&gt;FromEntity(EntityObject entity)&lt;/b&gt;, which retrieves the &lt;b&gt;NorthwindEntities&lt;/b&gt; instance to which that entity is attached, or &lt;b&gt;null&lt;/b&gt; if the entity is detached.&lt;/p&gt;

&lt;h4&gt;Solution 1: Dynamic&lt;/h4&gt;

&lt;p&gt;The idea behind this solution is to add a property to the entity type that points to its own &lt;b&gt;ObjectContext&lt;/b&gt;. It's possible to do this by &lt;a href="http://msdn.microsoft.com/en-us/library/dd456821.aspx"&gt;modifying the code-generating&lt;/a&gt; &lt;a href="http://msdn.microsoft.com/en-us/library/ff477605.aspx"&gt;template&lt;/a&gt; file, but it's also possible to just add the property to each entity type manually and use dynamic duck typing to access it.&lt;/p&gt;

&lt;p&gt;The modified &lt;b&gt;NorthwindEntities&lt;/b&gt; uses &lt;b&gt;OnContextCreated&lt;/b&gt; to hook into its constructor and set up event handlers to respond whenever an entity is added to or removed from this context. Each event handler uses dynamic duck typing to access an "ObjectContext" property on the entity; if no such property exists, the entity is ignored.&lt;/p&gt;

&lt;pre class="brush:csharp"&gt;
using System.ComponentModel;
using System.Data.Objects.DataClasses;
using Microsoft.CSharp.RuntimeBinder;

namespace WindowsFormsApplication1
{
  public partial class NorthwindEntities
  {
    partial void OnContextCreated()
    {
      this.ObjectMaterialized += (_, e) =&amp;gt;
      {
        try
        {
          dynamic entity = e.Entity;
          entity.ObjectContext = this;
        }
        catch (RuntimeBinderException)
        {
        }
      };
      this.ObjectStateManager.ObjectStateManagerChanged += (_, e) =&amp;gt;
      {
        if (e.Action == CollectionChangeAction.Add)
        {
          try
          {
            dynamic entity = e.Element;
            entity.ObjectContext = this;
          }
          catch (RuntimeBinderException)
          {
          }
        }
        else if (e.Action == CollectionChangeAction.Remove)
        {
          try
          {
            dynamic entity = e.Element;
            entity.ObjectContext = null;
          }
          catch (RuntimeBinderException)
          {
          }
        }
      };
    }

    /// &amp;lt;summary&amp;gt;
    /// Gets the object context for the entity. Returns &amp;lt;c&amp;gt;null&amp;lt;/c&amp;gt; if the entity is detached or does not define an &amp;lt;c&amp;gt;ObjectContext&amp;lt;/c&amp;gt; property.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;entity&amp;quot;&amp;gt;The entity for which to return the object context.&amp;lt;/param&amp;gt;
    public static NorthwindEntities FromEntity(EntityObject entity)
    {
      try
      {
        dynamic dynamicEntity = entity;
        return dynamicEntity.ObjectContext;
      }
      catch (RuntimeBinderException)
      {
        return null;
      }
    }
  }
}
&lt;/pre&gt;

&lt;p&gt;The disadvantage to this approach is that you have to add an &lt;b&gt;ObjectContext&lt;/b&gt; property to each entity type, like this:&lt;/p&gt;

&lt;pre class="brush:csharp"&gt;
namespace WindowsFormsApplication1
{
  public partial class Order
  {
    /// &amp;lt;summary&amp;gt; 
    /// Gets or sets the context for this entity.
    ///  This should not be set by end-user code; this property will be set
    ///  automatically as entities are created or added,
    ///  and will be set to &amp;lt;c&amp;gt;null&amp;lt;/c&amp;gt; as entities are detached.
    /// &amp;lt;/summary&amp;gt; 
    internal NorthwindEntities ObjectContext { get; set; }
  }
}
&lt;/pre&gt;

&lt;p&gt;Alternatively, you could modify the creation template. Either way, it's a fair amount of work.&lt;/p&gt;

&lt;h4&gt;Solution 2: Connected Properties&lt;/h4&gt;

&lt;p&gt;The &lt;a href="http://www.nuget.org/List/Packages/ConnectedProperties"&gt;Connected Properties&lt;/a&gt; library may be used to "attach" properties to entity objects at run-time. This means it's no longer necessary to add the &lt;b&gt;ObjectContext&lt;/b&gt; property on each entity type.&lt;/p&gt;

&lt;p&gt;This modified &lt;b&gt;NorthwindEntities&lt;/b&gt; uses the same hooks as the one above, but it uses connected properties instead of dynamic duck typing:&lt;/p&gt;

&lt;pre class="brush:csharp"&gt;
using System.ComponentModel;
using System.Data.Objects.DataClasses;
using Nito.ConnectedProperties;
using Nito.ConnectedProperties.Implicit;

namespace WindowsFormsApplication1
{
  public partial class NorthwindEntities
  {
    /// &amp;lt;summary&amp;gt;
    /// The object context connected property type.
    /// &amp;lt;/summary&amp;gt;
    private struct ObjectContextProperty { }

    /// &amp;lt;summary&amp;gt;
    /// Gets the object context connected property for a specified carrier object.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;entity&amp;quot;&amp;gt;The carrier object.&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;The connected property.&amp;lt;/returns&amp;gt;
    private static IConnectibleProperty&amp;lt;NorthwindEntities&amp;gt; ObjectContext(object entity)
    {
      return entity.GetConnectedProperty&amp;lt;NorthwindEntities, ObjectContextProperty&amp;gt;();
    }

    /// &amp;lt;summary&amp;gt;
    /// Handles post-construction event.
    /// &amp;lt;/summary&amp;gt;
    partial void OnContextCreated()
    {
      this.ObjectMaterialized += (_, e) =&amp;gt;
      {
        ObjectContext(e.Entity).Set(this);
      };

      this.ObjectStateManager.ObjectStateManagerChanged += (_, e) =&amp;gt;
      {
        if (e.Action == CollectionChangeAction.Add)
        {
          ObjectContext(e.Element).Set(this);
        }
        else if (e.Action == CollectionChangeAction.Remove)
        {
          ObjectContext(e.Element).Set(null);
        }
      };
    }

    /// &amp;lt;summary&amp;gt;
    /// Gets the object context for the entity. Returns &amp;lt;c&amp;gt;null&amp;lt;/c&amp;gt; if the entity is detached.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;entity&amp;quot;&amp;gt;The entity for which to return the object context.&amp;lt;/param&amp;gt;
    public static NorthwindEntities FromEntity(EntityObject entity)
    {
      return ObjectContext(entity).GetOrConnect(null);
    }
  }
}
&lt;/pre&gt;

&lt;p&gt;The disadvantage of this approach is that you do need to take a dependency on the &lt;a href="http://www.nuget.org/List/Packages/ConnectedProperties"&gt;Connected Properties&lt;/a&gt; library, but I think that's a reasonable tradeoff.&lt;/p&gt;

&lt;p&gt;This post was inspired by &lt;a href="http://stackoverflow.com/questions/5707312/whats-the-fastest-way-to-get-an-objectcontext-reference-from-an-entity-object"&gt;a recent SO question&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7297021906893122222-8258839092889204805?l=nitoprograms.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OlZtT/~4/o66p7YXo_Ws" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://nitoprograms.blogspot.com/feeds/8258839092889204805/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://nitoprograms.blogspot.com/2011/05/getting-objectcontext-from-entityobject.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/8258839092889204805?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/8258839092889204805?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OlZtT/~3/o66p7YXo_Ws/getting-objectcontext-from-entityobject.html" title="Getting the ObjectContext from an EntityObject" /><author><name>Stephen Cleary</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://nitoprograms.blogspot.com/2011/05/getting-objectcontext-from-entityobject.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEEEQH09eip7ImA9WhZWGE8.&quot;"><id>tag:blogger.com,1999:blog-7297021906893122222.post-7418294080775285988</id><published>2011-05-19T12:30:00.007-04:00</published><updated>2011-05-19T12:30:01.362-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-19T12:30:01.362-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Language design" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="Linq" /><title>Signed and Unsigned Comparisons in C, C#, and T-SQL</title><content type="html">&lt;p&gt;As noted earlier, I've been doing a lot of firmware development recently (in C). A long-standing rule of C (and C++) is to convert &lt;b&gt;signed int&lt;/b&gt; values to &lt;b&gt;unsigned int&lt;/b&gt; values if both are used in a comparison; this is what the standard specifies. It's also traditional to issue a warning (the famous &lt;i&gt;comparison between signed and unsigned integer expressions&lt;/i&gt; warning) because such code is usually a mistake.&lt;/p&gt;

&lt;p&gt;In C, the expression &lt;b&gt;( (unsigned)-1 == -1 )&lt;/b&gt; will compile (with a warning), and have a value of &lt;b&gt;1&lt;/b&gt; (true). C# and T-SQL both handle that situation very differently.&lt;/p&gt;

&lt;p&gt;In C#, the expression &lt;b&gt;( unchecked((uint)-1) == -1 )&lt;/b&gt; will compile without warning and have a value of &lt;b&gt;false&lt;/b&gt;. What &lt;a href="http://msdn.microsoft.com/en-us/library/aa691330(v=VS.71).aspx"&gt;actually happens&lt;/a&gt; (&lt;a href="http://www.webcitation.org/5ySVSNhTE"&gt;webcite&lt;/a&gt;) is that the unsigned value of 0xFFFFFFFF and the signed value of -1 are both converted to &lt;b&gt;long&lt;/b&gt; values and &lt;i&gt;then&lt;/i&gt; compared.&lt;/p&gt;

&lt;p&gt;The C# behavior does makes sense. C# continues the C/C++ tradition of implicitly promoting to &lt;b&gt;int&lt;/b&gt; for any integral binary operation (e.g., two &lt;b&gt;byte&lt;/b&gt; values added together are converted to &lt;b&gt;int&lt;/b&gt;s before the addition). However, the additional implicit promotion to &lt;b&gt;long&lt;/b&gt; was a bit of a surprise. This is probably due to 64-bit math becoming more commonplace - not common enough to have an implicit promotion to &lt;b&gt;long&lt;/b&gt; for &lt;i&gt;every&lt;/i&gt; binary operation, but enough to add the implicit promotion to &lt;b&gt;long&lt;/b&gt; when necessary.&lt;/p&gt;

&lt;p&gt;In SQL Server's TSQL, the expression &lt;b&gt;select 'true' where -1 = 4294967295;&lt;/b&gt; will return an empty result set (meaning &lt;b&gt;-1&lt;/b&gt; is not considered equivalent to &lt;b&gt;4294967295&lt;/b&gt;). Interestingly, it's doing the &lt;a href="http://msdn.microsoft.com/en-us/library/ms190309.aspx"&gt;same kind of promotion as C#&lt;/a&gt; (&lt;a href="http://www.webcitation.org/5ySZdwwtV"&gt;webcite&lt;/a&gt;). In this case, the value &lt;b&gt;4294967295&lt;/b&gt; is typed as a &lt;b&gt;bigint&lt;/b&gt; (a 64-bit signed integer).&lt;/p&gt;

&lt;p&gt;The C# behavior can be seen when inspecting T-SQL statements generated by Linq to Entites. In my case, I was using code such as this to look up an item by serial number (an unsigned value):&lt;/p&gt;

&lt;pre class="brush:csharp"&gt;
using (var context = new MyEntities())
{
    uint serialNumber = 0xFFFFFFFF;
    var item = context.Items.Where(x =&amp;gt; x.SerialNumber == serialNumber).SingleOrDefault();
}
&lt;/pre&gt;

&lt;p&gt;The generated T-SQL statement (for SQL Server Compact Edition) was like this:&lt;/p&gt;

&lt;pre&gt;
SELECT TOP (2) [Extent1].[ID] AS [ID], [Extent1].[SerialNumber] AS [SerialNumber] FROM [Items] AS [Extent1]  WHERE ( CAST( [Extent1].[SerialNumber] AS bigint)) = @p__linq__0
&lt;/pre&gt;

&lt;p&gt;&lt;b&gt;p__linq__0&lt;/b&gt; had a &lt;a href="http://msdn.microsoft.com/en-us/library/system.data.dbtype.aspx"&gt;DbType&lt;/a&gt; of &lt;b&gt;Int64&lt;/b&gt;. Note that the generated T-SQL includes an explicit cast to &lt;b&gt;bigint&lt;/b&gt; because the C# language implicitly inserted a cast to &lt;b&gt;long&lt;/b&gt; in the expression &lt;b&gt;x.SerialNumber == serialNumber&lt;/b&gt;.&lt;/p&gt;

&lt;p&gt;Lesson learned: be careful of mixing signed and unsigned types. The warnings that existed in C/C++ are not necessarily present in C# (or T-SQL).&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7297021906893122222-7418294080775285988?l=nitoprograms.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OlZtT/~4/Z06ik42ZLW0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://nitoprograms.blogspot.com/feeds/7418294080775285988/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://nitoprograms.blogspot.com/2011/05/signed-and-unsigned-comparisons-in-c-c.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/7418294080775285988?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/7418294080775285988?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OlZtT/~3/Z06ik42ZLW0/signed-and-unsigned-comparisons-in-c-c.html" title="Signed and Unsigned Comparisons in C, C#, and T-SQL" /><author><name>Stephen Cleary</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://nitoprograms.blogspot.com/2011/05/signed-and-unsigned-comparisons-in-c-c.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DU4FRXc9eyp7ImA9WhZWE00.&quot;"><id>tag:blogger.com,1999:blog-7297021906893122222.post-765412694783577912</id><published>2011-05-12T12:05:00.001-04:00</published><updated>2011-05-13T13:31:54.963-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-13T13:31:54.963-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="Windows Services" /><title>Managed Services and UIs</title><content type="html">&lt;p&gt;One common question that I've seen is how to display a UI from a service.&lt;/p&gt;

&lt;p&gt;The answer is: "don't".&lt;/p&gt;

&lt;p&gt;Usually, when someone asks this question, the correct solution is to change the application from a &lt;i&gt;service&lt;/i&gt; to a background application run whenever a user logs in (e.g., from the Startup folder), possibly with a tray icon. Occasionally, this isn't possible, and the correct solution in that case is to split the application into two applications: a service without a UI, and a UI front-end (which may be a backround application run automatically).&lt;/p&gt;

&lt;p&gt;Unfortunately, some people try to push forward with the "service with a UI" approach. This is doomed to fail.&lt;/p&gt;

&lt;h4&gt;Inevitable Failure&lt;/h4&gt;

&lt;p&gt;There are two hurdles to displaying a UI from a service; the first is architectural, and the second is technical.&lt;/p&gt;

&lt;p&gt;The architectural hurdle is simply that displaying a UI from a service just doesn't make sense. A Win32 service is a program that runs (or can be run) any time the computer is running, regardless of whether or not there is a user logged in. It doesn't make much sense to talk about "displaying a UI" if there isn't a user to show it to. Also consider multi-user (terminal server or fast-user-switching) computers: &lt;i&gt;which&lt;/i&gt; user would see the UI?&lt;/p&gt;

&lt;p&gt;The technical hurdle is a bit more complex. To summarize: services which display UIs are a security risk.&lt;/p&gt;

&lt;p&gt;The Win32 windows messaging system was designed without security in mind. Before you get too mad at Microsoft, remember that the Internet (including email, TCP/IP, and HTTP) were designed without security, too. Back then, it was hard enough just to get it working, without worrying about someone deliberately trying to destroy it. Most security on the Internet today is due to wrapping the original insecure protocols in an encrypted, authenticated stream (SSL/TLS).&lt;/p&gt;

&lt;blockquote&gt;In fact, when I first got on the Internet, the common instructions for setting up an email server explicitly stated that it should be set up as an open relay so that anyone could send email through it. Then someone invented spam. The instructions have since been revised.&lt;/blockquote&gt;

&lt;p&gt;Similarly, in the early days, Windows had no need for security. In early versions of Windows, multitasking was non-preemptive, so any program could effortlessly cause a denial-of-service attack. Furthermore, each program had direct access to hardware, and causing a complete system crash was trivial.&lt;/p&gt;

&lt;p&gt;These days, the situation is much improved. On modern OSes (not including the 9x line), a user-mode program simply cannot crash the system; it can only crash itself. With almost every new OS, Microsoft has enhanced security by trusting programs less (e.g., User Account Control).&lt;/p&gt;

&lt;p&gt;One attack vector for malicious programs is a &lt;i&gt;privilege escalation&lt;/i&gt;. This is a way for an untrusted program to trick the OS into trusting it more. One privilege escalation attack that has been discovered is called a &lt;a href="http://en.wikipedia.org/wiki/Shatter_attack"&gt;shatter attack&lt;/a&gt;. This "shatter attack" is based on Win32 message passing.&lt;/p&gt;

&lt;p&gt;In response, Microsoft made two changes starting in Vista: User Interface Privilege Isolation (see &lt;a href="http://msdn.microsoft.com/en-us/library/bb756960.aspx"&gt;New UAC Technologies for Windows Vista&lt;/a&gt; (&lt;a href="http://www.webcitation.org/5yJMQ8H2i"&gt;webcite&lt;/a&gt;)); and Session 0 Isolation (see &lt;a href="http://blogs.technet.com/b/askperf/archive/2007/04/27/application-compatibility-session-0-isolation.aspx"&gt;this Application Compatibility blog post&lt;/a&gt; (&lt;a href="http://www.webcitation.org/5yJcr5ySR"&gt;webcite&lt;/a&gt;) or &lt;a href="http://msdn.microsoft.com/en-us/windows/hardware/gg463353"&gt;this Word document&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;User Interface Privilege Isolation is a simple system where less-trusted programs (such as Internet Explorer) are limited in which Win32 messages they may send to more-trusted programs (such as services). This doesn't prevent services from having UIs, but may trip up programmers if they try to communicate with their service via message passing.&lt;/p&gt;

&lt;p&gt;Session 0 Isolation is more surprising to most programmers, simply because most programmers are not aware of desktops or window stations. The following MSDN resources provide a good intro to the concept:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://support.microsoft.com/kb/171890"&gt;Services, Desktops, and Window Stations (KB171890)&lt;/a&gt; (&lt;a href="http://www.webcitation.org/5yJMygiUo"&gt;webcite&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms684859.aspx"&gt;Process Connection to a Window Station&lt;/a&gt; (&lt;a href="http://www.webcitation.org/5yJN86Gvo"&gt;webcite&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms686744.aspx"&gt;Thread Connection to a Desktop&lt;/a&gt; (&lt;a href="http://www.webcitation.org/5yJNBEJc4"&gt;webcite&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In essence, the older versions of Windows (XP and earlier) would run services in the same session as the first user that logged on to the physical computer, and services displaying UIs would be seen by that user. Newer versions of Windows (Vista and later) run services in their own special session (Session 0), which has its own window station and desktop completely independent from anything the user sees.&lt;/p&gt;

&lt;p&gt;Naturally, this broke a lot of existing services, so Microsoft implemented a couple of workarounds. One is the "Interactive Service" flag, which would allow a service to display a UI. Another is the Interactive Service Detection Service, which is a special service that detects dialogs on Session 0 and notifies the user (if any) of them.&lt;/p&gt;

&lt;p&gt;It is possible to set the Interactive Service flag when installing a service (not through the regular .NET Framework APIs; you have to p/Invoke for it). That is a horrible hack and should never, ever be applied to a new application. Even with that flag, some notification systems may not work as expected (see the end of &lt;a href="http://blogs.technet.com/b/voy/archive/2007/02/23/services-isolation-in-session-0-of-windows-vista-and-longhorn-server.aspx"&gt;this blog post from the security team&lt;/a&gt; (&lt;a href="http://www.webcitation.org/5yJd1Jb7p"&gt;webcite&lt;/a&gt;)).&lt;/p&gt;

&lt;p&gt;Remember that the Interactive Service flag is a &lt;i&gt;backwards&lt;/i&gt; compatibility hack that weakens overall system security and may be removed from Windows vNext. Similarly, the Interactive Service Detection Service comes with this disclaimer: "This support might be removed from a future Windows release, at which time all applications and drivers must handle Session 0 isolation properly."&lt;/p&gt;

&lt;p&gt;So - while it is &lt;i&gt;possible&lt;/i&gt; to hack together a service with a UI today - you'd only be setting yourself up for failure in the future.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7297021906893122222-765412694783577912?l=nitoprograms.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OlZtT/~4/vZARHCfrW0Y" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://nitoprograms.blogspot.com/feeds/765412694783577912/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://nitoprograms.blogspot.com/2011/05/managed-services-and-uis.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/765412694783577912?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/765412694783577912?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OlZtT/~3/vZARHCfrW0Y/managed-services-and-uis.html" title="Managed Services and UIs" /><author><name>Stephen Cleary</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://nitoprograms.blogspot.com/2011/05/managed-services-and-uis.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcEQXo7eCp7ImA9WhZXFkw.&quot;"><id>tag:blogger.com,1999:blog-7297021906893122222.post-1042421121410476367</id><published>2011-05-05T12:30:00.000-04:00</published><updated>2011-05-05T12:30:00.400-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-05T12:30:00.400-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="Linq" /><category scheme="http://www.blogger.com/atom/ns#" term="Simple and Easy" /><title>Simple and Easy Entity Framework SQL Tracing</title><content type="html">&lt;p&gt;There's an easy way to &lt;a href="http://nitoprograms.blogspot.com/2010/12/simple-and-easy-tracing-in-net.html"&gt;add tracing to an application&lt;/a&gt;, but Entity Framework brings some special challenges. &lt;a href="http://msdn.microsoft.com/en-us/library/system.data.objects.objectquery.totracestring.aspx"&gt;ObjectQuery.ToTraceString&lt;/a&gt; does allow tracing of SQL SELECT commands, but there's no built-in way to trace database updates.&lt;/p&gt;

&lt;p&gt;However, there is an &lt;a href="http://efwrappers.codeplex.com/"&gt;Entity Framework Tracing Provider&lt;/a&gt; that allows this. Follow the quick-start instructions on the home page, and you'll be off in no time!&lt;/p&gt;

&lt;p&gt;Here's a few tests using SQL Server Compact Edition to access the Northwind sample database. This code:&lt;/p&gt;

&lt;pre class="brush:csharp"&gt;
using (var db = new NorthwindContext())
{
    MessageBox.Show(db.Orders.Count(x =&amp;gt; x.Order_Date &amp;lt; DateTime.Now).ToString());
}
&lt;/pre&gt;

&lt;p&gt;will result in this trace:&lt;/p&gt;

&lt;pre&gt;
EntityFramework.NorthwindEntities Information: 0 : Executing 1: SELECT [GroupBy1].[A1] AS [C1] FROM ( SELECT COUNT(1) AS [A1] FROM [Orders] AS [Extent1] WHERE [Extent1].[Order Date] &amp;lt; ( CAST( GetDate() AS datetime)) ) AS [GroupBy1]
EntityFramework.NorthwindEntities Information: 0 : Finished 1 in 00:00:00.0466592: [DbDataReader(C1:Int)]
&lt;/pre&gt;

&lt;p&gt;Note that the total time taken by the query is included in the finishing trace. Another interesting tidbit is that &lt;i&gt;DateTime.Now&lt;/i&gt; is not evaluated on the client side; rather, the SQL statement includes a call to &lt;i&gt;GetDate&lt;/i&gt;.&lt;/p&gt;

&lt;p&gt;Here's some code that deletes an order:&lt;/p&gt;

&lt;pre class="brush:csharp"&gt;
using (var db = new NorthwindContext())
{
    db.Orders.DeleteObject(db.Orders.OrderBy(x =&amp;gt; x.Order_Date).First());
    db.SaveChanges();
}
&lt;/pre&gt;

&lt;p&gt;resulting in this trace:&lt;/p&gt;

&lt;pre&gt;
EntityFramework.NorthwindEntities Information: 0 : Executing 2: SELECT TOP (1) [Extent1].[Order ID] AS [Order ID], [Extent1].[Customer ID] AS [Customer ID], [Extent1].[Employee ID] AS [Employee ID], [Extent1].[Ship Name] AS [Ship Name], [Extent1].[Ship Address] AS [Ship Address], [Extent1].[Ship City] AS [Ship City], [Extent1].[Ship Region] AS [Ship Region], [Extent1].[Ship Postal Code] AS [Ship Postal Code], [Extent1].[Ship Country] AS [Ship Country], [Extent1].[Ship Via] AS [Ship Via], [Extent1].[Order Date] AS [Order Date], [Extent1].[Required Date] AS [Required Date], [Extent1].[Shipped Date] AS [Shipped Date], [Extent1].[Freight] AS [Freight] FROM [Orders] AS [Extent1] ORDER BY [Extent1].[Order Date] ASC
EntityFramework.NorthwindEntities Information: 0 : Finished 2 in 00:00:00.0027257: [DbDataReader(Order ID:Int, Customer ID:NVarChar, Employee ID:Int, Ship Name:NVarChar, Ship Address:NVarChar, Ship City:NVarChar, Ship Region:NVarChar, Ship Postal Code:NVarChar, Ship Country:NVarChar, Ship Via:Int, Order Date:DateTime, Required Date:DateTime, Shipped Date:DateTime, Freight:Money)]
EntityFramework.NorthwindEntities Information: 0 : Executing 3: delete [Orders] where ([Order ID] = @0) { @0=[Int32,0,Input]10000 }
EntityFramework.NorthwindEntities Information: 0 : Finished 3 in 00:00:00.0482807: 1 rows affected
&lt;/pre&gt;

&lt;p&gt;As expected, the first command executes a single-row SELECT, followed by a DELETE that affects a single row. Note the use of the parameterized deletion query.&lt;/p&gt;

&lt;p&gt;Unfortunately, the Entity Framework Tracing Provider does not support everything; in particular, direct database commands (e.g., &lt;a href="http://msdn.microsoft.com/en-us/library/system.data.objects.objectcontext.executestorecommand.aspx"&gt;ExecuteStoreCommand&lt;/a&gt;) are not supported.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7297021906893122222-1042421121410476367?l=nitoprograms.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OlZtT/~4/CQZ7TyLzZlM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://nitoprograms.blogspot.com/feeds/1042421121410476367/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://nitoprograms.blogspot.com/2011/05/simple-and-easy-entity-framework-sql.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/1042421121410476367?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/1042421121410476367?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OlZtT/~3/CQZ7TyLzZlM/simple-and-easy-entity-framework-sql.html" title="Simple and Easy Entity Framework SQL Tracing" /><author><name>Stephen Cleary</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://nitoprograms.blogspot.com/2011/05/simple-and-easy-entity-framework-sql.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUIMSHk5eyp7ImA9WhZXEE8.&quot;"><id>tag:blogger.com,1999:blog-7297021906893122222.post-7669822473643049478</id><published>2011-04-28T17:53:00.000-04:00</published><updated>2011-04-28T17:53:09.723-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-28T17:53:09.723-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Threading" /><category scheme="http://www.blogger.com/atom/ns#" term="P/Invoke" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><title>Unmanaged Blocking</title><content type="html">&lt;p&gt;Managed code should never block in an unmanaged function, if it can possibly help it. As a general rule, wait functions (such as &lt;b&gt;WaitForMultipleObjects&lt;/b&gt;) should never be p/Invoked from managed code.&lt;/p&gt;

&lt;p&gt;The MSDN document &lt;a href="http://msdn.microsoft.com/en-us/library/ms228970.aspx"&gt;Reliability Best Practices&lt;/a&gt; (&lt;a href="http://www.webcitation.org/5yHvHIG97"&gt;webcite&lt;/a&gt;) states "do not block indefinitely in unmanaged code." Specifically, "blocking using a Win32 synchronization primitive is a clear example of something we cannot allow" because "a blocked thread prevents the CLR from unloading the AppDomain, at least without doing some extremely unsafe operations." As a general rule, they suggest that any function blocking more than 10 seconds will &lt;i&gt;require special CLR support!&lt;/i&gt; In other words, if you're doing unmanaged blocking for that long, you'll have to write your own .NET runtime host.&lt;/p&gt;

&lt;p&gt;The legendary Chris Brumme has a good blog entry on &lt;a href="http://blogs.msdn.com/b/cbrumme/archive/2003/04/17/51361.aspx"&gt;Managed Blocking&lt;/a&gt; (&lt;a href="http://www.webcitation.org/5yHvfrmgy"&gt;webcite&lt;/a&gt;). He enumerates several reasons why unmanaged blocking is inappropriate:

&lt;ul&gt;
&lt;li&gt;The CLR loses control of the thread. This is the same reason covered in the MSDN article above.&lt;/li&gt;
&lt;li&gt;Managed blocking will do message pumping (in the right way) while blocked. This is necessary for STA threads (including UI threads as well as threads doing STA COM interop). Mr. Blumme has another classic classic blog entry: &lt;a href="http://blogs.msdn.com/b/cbrumme/archive/2004/02/02/66219.aspx"&gt;Apartments and Pumping in the CLR&lt;/a&gt; (&lt;a href="http://www.webcitation.org/5yHvxNIih"&gt;webcite&lt;/a&gt;) that delves in-depth into this issue, and is probably the most complex blog post in existence.&lt;/li&gt;
&lt;li&gt;The CLR collects information about managed threads, including how often and how long they block; this information is used (among other things) for making the ThreadPool more efficient. Unmanaged blocking prevents the CLR from gathering this information.&lt;/li&gt;
&lt;li&gt;(The fourth reason from the blog post - hiding of platform differences - is no longer applicable, since the Windows 9x line is no longer supported by modern .NET applications).
&lt;/ul&gt;

&lt;p&gt;Joe Duffy, in a very interesting post on &lt;a href="http://www.bluebytesoftware.com/blog/PermaLink,guid,710e6ba3-60e9-4f5e-a5a7-d878015c7a16.aspx"&gt;Hooking CLR Calls with SynchronizationContext&lt;/a&gt; (&lt;a href="http://www.webcitation.org/5yHvuG9w1"&gt;webcite&lt;/a&gt;), talks about using a custom &lt;b&gt;SynchronizationContext&lt;/b&gt; implementation to receive notifications about managed blocking. These types of notifications simply won't work if a managed thread does unmanaged blocking.&lt;/p&gt;

&lt;p&gt;Closely related to Joe Duffy's post above is the fact that some CLR hosts take special action when managed threads block. In particular, SQL Server makes use of that information. Any host that is based on fibers instead of threads would also require that information (AutoCAD is the only such host that I'm aware of). Again, unmanaged blocking would prevent these hosts from working as expected.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.threading.waithandle.aspx"&gt;&lt;b&gt;WaitHandle&lt;/b&gt;&lt;/a&gt; is the key to unusual managed blocking situations. You can wait on any or all of a series of handles, or even derive from the &lt;b&gt;WaitHandle&lt;/b&gt; class itself if you have a Win32 synchronization primitive not already wrapped by the BCL.&lt;/p&gt;

&lt;p&gt;The bottom line is: avoid unmanaged blocking.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7297021906893122222-7669822473643049478?l=nitoprograms.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OlZtT/~4/QOChWtbwxSk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://nitoprograms.blogspot.com/feeds/7669822473643049478/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://nitoprograms.blogspot.com/2011/04/unmanaged-blocking.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/7669822473643049478?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7297021906893122222/posts/default/7669822473643049478?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OlZtT/~3/QOChWtbwxSk/unmanaged-blocking.html" title="Unmanaged Blocking" /><author><name>Stephen Cleary</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://nitoprograms.blogspot.com/2011/04/unmanaged-blocking.html</feedburner:origLink></entry></feed>

