<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Talk Nerdy To Me - Java, C#, .Net &#187; CodeProject</title>
	<atom:link href="http://www.gavaghan.org/blog/category/codeproject/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.gavaghan.org/blog</link>
	<description>Mike Gavaghan blogs on Java, C#, .Net, and the software industry</description>
	<lastBuildDate>Mon, 22 Feb 2010 22:09:03 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>TCP/IP Parameter Tuning for Rapid Client Connections</title>
		<link>http://www.gavaghan.org/blog/2010/02/17/tcpip-parameter-tuning-for-rapid-client-connections/</link>
		<comments>http://www.gavaghan.org/blog/2010/02/17/tcpip-parameter-tuning-for-rapid-client-connections/#comments</comments>
		<pubDate>Wed, 17 Feb 2010 19:37:36 +0000</pubDate>
		<dc:creator>Mike Gavaghan</dc:creator>
				<category><![CDATA[CodeProject]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://www.gavaghan.org/blog/2010/02/17/tcpip-parameter-tuning-for-rapid-client-connections/</guid>
		<description><![CDATA[Applications that open and close a large number of client TCP/IP sockets run the risk of running out of available socket ports.  This can happen in a load and performance testing scenario using a tool like LISA Test from iTKO, or it could happen in a production environment if an active application simply needs to rapidly open and close a large number of outbound connections.

On the .NET platform, the exception raised reads "System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted <host>:<port>".

In Java, the exception is "java.net.BindException: Address already in use: connect".  

Both exceptions are misleading because they are generally associated with server socket conflicts – not outbound client socket connections.  However, a better understanding of the TCP state machine sheds some light on this behavior - and a solution.]]></description>
			<content:encoded><![CDATA[<p>Applications that open and close a large number of client TCP/IP sockets run the risk of running out of available socket ports.  This can happen in a load and performance testing scenario using a tool like <a target="_blank" href="http://www.itko.com/products/lisatest.jsp" title="LISA Test - QA Software for Composite Enterprise Applications and SOA">LISA Test</a> from <a target="_blank" href="http://www.itko.com/" title="LISA Virtualization and Validation Software for Modern Applications: SOA, Cloud, and BPM">iTKO</a>, or it could happen in a production environment if an active application simply needs to rapidly open and close a large number of outbound connections.</p>
<p>On the <strong>.NET</strong> platform, the exception raised reads &#8220;<code><a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.net.sockets.socketexception.aspx" title="SocketException">System.Net.Sockets.SocketException</a>: Only one usage of each socket address (protocol/network address/port) is normally permitted &lt;host&gt;:&lt;port&gt;</code>&#8220;. </p>
<p><strong>In Java</strong>, the exception is &#8220;<code><a target="_blank" href="http://java.sun.com/javase/6/docs/api/java/net/BindException.html" title="Java BindException">java.net.BindException</a>: Address already in use: connect</code>&#8220;. </p>
<p>Both exceptions are misleading because they are generally associated with server socket conflicts – not outbound client socket connections.  However, a better understanding of the <a target="_blank" href="http://www.night-ray.com/TCPIP_State_Transition_Diagram.pdf" title="TCP Finite State Machine">TCP state machine</a> sheds some light on this behavior &#8211; and a solution.</p>
<p><span id="more-69"></span><strong>Common Port Conflict Exceptions</strong></p>
<p>Whenever TCP/IP encounters a port conflict, you can expect one of the two following exceptions to be thrown depending upon your environment:</p>
<p>In a C# environment, you&#8217;ll see this exception:</p>
<blockquote class="codeblock">
<blockquote class="codeline0"><p>System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted &lt;host&gt;:&lt;port&gt;</p></blockquote>
</blockquote>
<p>In Java, you&#8217;ll see this:</p>
<blockquote class="codeblock">
<blockquote class="codeline0"><p>java.net.BindException: Address already in use: connect</p></blockquote>
<blockquote class="codeline1"><p>at java.net.PlainSocketImpl.socketConnect(Native Method)</p></blockquote>
<blockquote class="codeline1"><p>at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)</p></blockquote>
<blockquote class="codeline1"><p>at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)</p></blockquote>
<blockquote class="codeline1"><p>at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)</p></blockquote>
<blockquote class="codeline1"><p>at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)</p></blockquote>
<blockquote class="codeline1"><p>at java.net.Socket.connect(Socket.java:519)</p></blockquote>
<blockquote class="codeline1"><p>at java.net.Socket.connect(Socket.java:469)</p></blockquote>
</blockquote>
<p>If you see these exceptions thrown when a <u>server</u> socket attempts to listen for incoming connections, the cause is obvious: the port you&#8217;re attempting to listen on is already in use.  For example, if you bring up a Web server, but another Web server is already running, an exception will be thrown because port 80 (or 8080) is already listening on behalf of another thread or application.</p>
<p>These exceptions are often confusing, however, when thrown setting up a <u>client</u> connection.  Client TCP connections are always assigned an OS-selected port on the local side, so why is the operating system selecting an active port?  The truth is the exception indicates <u><strong>no</strong></u> local port numbers are available to the client.  This misreporting of the error by the OS is half the confusion.</p>
<p><strong>Tuning Local Client Port Range</strong></p>
<p>The problem is two-fold.  First, Linux and Windows make only a certain number of ports available to client sockets – the default is in the range of 1024 to 5000.  Hence, you may have only 3,976 active client connections at a time.  For most systems, this is plenty.  However, in specific circumstances on systems requiring a large number of outbound connections, this limit can be exhausted.</p>
<p>This range, however, can be tuned.  On Windows,  the upper bound for client port assignments can be adjusted using the <a target="_blank" href="http://technet.microsoft.com/en-us/library/cc758002%28WS.10%29.aspx" title="MaxUserPort"><code>MaxUserPort</code></a> <code>DWORD</code> value on this registry key:</p>
<blockquote class="codeblock">
<blockquote class="codeline0"><p>HKLM\System\CurrentControlSet\Services\Tcpip\Parameters</p></blockquote>
</blockquote>
<p>Of course, rather than using the cumbersome <code>regedit</code>, you can <a target="_blank" href="http://www.gavaghan.org/blog/free-source-code/ip-tuner/" onclick="javascript:urchinTracker('/outgoing/free_source_code_iptuner');" title="Gavaghan TCP/IP Parameter Tuning for Windows">download IPTuner for free</a> to quickly optimize your Windows IP stack</p>
<p>On Linux, both the lower and upper bounds can be set using the following parameter:</p>
<blockquote class="codeblock">
<blockquote class="codeline0"><p>net.ipv4.ip_local_port_range = 32768 65536</p></blockquote>
</blockquote>
<p>How this parameter is set in Linux varies depending upon the flavor and version of Linux you&#8217;re using – and you&#8217;ll need to restart networking after you change it.</p>
<p><strong>Tuning TCP TIME_WAIT Timeout Value</strong></p>
<p>The second cause of these exceptions has to do with the <a target="_blank" href="http://www.night-ray.com/TCPIP_State_Transition_Diagram.pdf" title="TCP State Model">TCP state model</a> and the way sockets are closed.  Even after a socket has officially been &#8220;closed&#8221;, it hangs around in a <code>TIME_WAIT</code> state as a safety mechanism to deal with stray packets.  The default wait time on all operating systems, generally, is ridiculously long (240 seconds on Windows).  So, even if an application doesn’t require a lot of concurrent connections, it can still run out of available ports in a high load situation.  If even one connection is repeatedly opened and closed fast enough, you&#8217;ll soon have all available local sockets hanging around in a <code>TIME_WAIT</code> state and none available for new clients.</p>
<p>The <code>TIME_WAIT</code> state duration, however, is also tunable.</p>
<p>On Windows, using the same registry key, the <code><a target="_blank" href="http://technet.microsoft.com/en-us/library/cc938217.aspx" title="TcpTimedWaitDelay">TCPTimedWaitDelay</a></code> value can be used to adjust the <code>TIME_WAIT</code> duration from 30 to 300 seconds.  Of course, rather than using the cumbersome <code>regedit</code>, you can <a target="_blank" href="http://www.gavaghan.org/blog/free-source-code/ip-tuner/" onclick="javascript:urchinTracker('/outgoing/free_source_code_iptuner');" title="Gavaghan TCP/IP Parameter Tuning for Windows">download IPTuner for free</a> to quickly optimize your Windows IP stack.</p>
<p>On Linux, the wait delay is configured using the following parameter:</p>
<blockquote class="codeblock">
<blockquote class="codeline0"><p>net.ipv4.tcp_fin_timeout = 30</p></blockquote>
</blockquote>
<p>By decreasing the TCP wait delay, closed sockets spend less time in the <code>TIME_WAIT</code> state and get returned to the pool of available client ports faster. However, to avoid communication problems, do not lower this value below 30 seconds.</p>
<p><strong>Administrator Privileges Required</strong></p>
<p>On both Linux and Windows (even if using <strong>IP tuner</strong> or <code>regedit</code>), you&#8217;ll require administrator privileges to change these parameters.  However, anyone can view these settings to at least verify if they make sense.</p>
<ul class="download">
<li><strong><a href="http://www.gavaghan.org/blog/free-source-code/ip-tuner/" onclick="javascript:urchinTracker('/outgoing/free_source_code_iptuner');" title="Gavaghan TCP/IP Parameter Tuner for Windows">Download <strong>IPTuner</strong> for Windows here.</a></strong></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.gavaghan.org/blog/2010/02/17/tcpip-parameter-tuning-for-rapid-client-connections/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The .NET Asynchronous I/O Design Pattern</title>
		<link>http://www.gavaghan.org/blog/2010/02/11/the-net-asynchronous-io-design-pattern/</link>
		<comments>http://www.gavaghan.org/blog/2010/02/11/the-net-asynchronous-io-design-pattern/#comments</comments>
		<pubDate>Thu, 11 Feb 2010 19:08:49 +0000</pubDate>
		<dc:creator>Mike Gavaghan</dc:creator>
				<category><![CDATA[CodeProject]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://www.gavaghan.org/blog/2010/02/11/the-net-asynchronous-io-design-pattern/</guid>
		<description><![CDATA[Asynchronous operations allow a program to perform time consuming tasks on a background thread while the main application continues to execute.  For example, consider when a program makes a request to a remote system.  In a single-threaded scenario, the call is made and the CPU goes idle as the caller waits on the server's processing time and the network latency.  If this waiting time can be delegated to a separate thread of execution, the program can complete other tasks until it receives notification the background work is complete.

However, managing multiple threads and cross-thread communication adds complexity to your code.  Fortunately, the .NET Framework has a useful design pattern applied to its I/O classes which easily enables asynchronous calls.  Let's take a look at an example.]]></description>
			<content:encoded><![CDATA[<p><a target="_blank" href="http://en.wikipedia.org/wiki/Asynchronous_I/O" title="Asynchronous I/O">Asynchronous operations</a> allow a program to perform time consuming tasks on a background thread while the main application continues to execute.  For example, consider when a program makes a request to a remote system.  In a single-threaded scenario, the call is made and the CPU goes idle as the caller waits on the server&#8217;s processing time and the network latency.  If this waiting time can be delegated to a separate thread of execution, the program can complete other tasks until it receives notification the background work is complete.</p>
<p>However, managing multiple threads and cross-thread communication adds complexity to your code.  Fortunately, the .NET Framework has a useful design pattern applied to its I/O classes which easily enables asynchronous calls.  Let&#8217;s take a look at an example.</p>
<p><span id="more-68"></span><strong>Async I/O for a DNS lookup</strong> </p>
<p>Suppose you need to lookup the IP address of a host.  The simplest way to do this is to use the <code><a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.net.dns.aspx" title="System.Net.Dns">System.Net.Dns</a></code> class:</p>
<blockquote class="codeblock">
<blockquote class="codeline0"><p>IPAddress[] hostAddresses = Dns.GetHostAddresses(&#8220;www.gavaghan.org&#8221;);</p></blockquote>
</blockquote>
<p>A DNS lookup doesn&#8217;t take terribly long and, in most cases, the synchronous example above is fine.  DNS servers are highly efficient, and local DNS servers will cache authoritative data to optimize response times.</p>
<p>However, suppose you&#8217;re implementing a high performance mail server that detects spam by querying multiple <a target="_blank" href="http://www.gavaghan.org/blog/2008/06/11/kill-spam-with-real-time-dns-blacklists/" title="DNS Blacklist - DNSBL">real time DNS blacklists</a>.  For every incoming message, you must execute a dozen DNS operations:</p>
<blockquote class="codeblock">
<blockquote class="codeline0"><p>IPAddress[] spamcop = Dns.GetHostAddresses(&#8220;22.154.199.213.bl.spamcop.net&#8221;);</p></blockquote>
<blockquote class="codeline0"><p>IPAddress[] spamhaus = Dns.GetHostAddresses(&#8220;22.154.199.213.pbl.spamhaus.org&#8221;);</p></blockquote>
<blockquote class="codeline0"><p>IPAddress[] fiveten =</p></blockquote>
<blockquote class="codeline5"><p>Dns.GetHostAddresses(&#8220;22.154.199.213.blackholes.five-ten-sg.com&#8221;);</p></blockquote>
<blockquote class="codeline0"><p>//</p></blockquote>
<blockquote class="codeline0"><p>// . . . and a dozen others</p></blockquote>
<blockquote class="codeline0"><p>//</p></blockquote>
</blockquote>
<p>Each synchronous lookup blocks waiting for a response before moving on to the next lookup.  The cumulative effect of these delays will get costly.  Ideally, you&#8217;d want to perform each lookup on its own thread and let the requests run concurrently.</p>
<p>So, let&#8217;s implement a method that looks like this:</p>
<blockquote class="codeblock">
<blockquote class="codeline0"><p>public class AsyncDNSExample</p></blockquote>
<blockquote class="codeline0"><p>{</p></blockquote>
<blockquote class="codeline2"><p>public List&lt;IPAddress&gt; MultiHostLookup(List&lt;string&gt; hosts)</p></blockquote>
<blockquote class="codeline2"><p>{</p></blockquote>
</blockquote>
<p>This method will accept a list of host names, execute concurrent DNS lookups for all of them, and return with a list of resolved addresses.  Here&#8217;s how we might use this method:</p>
<blockquote class="codeblock">
<blockquote class="codeline0"><p>class Program</p></blockquote>
<blockquote class="codeline0"><p>{</p></blockquote>
<blockquote class="codeline2"><p>static void Main()</p></blockquote>
<blockquote class="codeline2"><p>{</p></blockquote>
<blockquote class="codeline4"><p>// build list of hosts to lookup</p></blockquote>
<blockquote class="codeline4"><p>List&lt;string&gt; hosts = new List&lt;string&gt;();</p></blockquote>
<blockquote class="codeline4"><p>hosts.Add(&#8220;www.gavaghan.org&#8221;);</p></blockquote>
<blockquote class="codeline4"><p>hosts.Add(&#8220;www.itko.com&#8221;);</p></blockquote>
<blockquote class="codeline4"><p>hosts.Add(&#8220;sombrita.com&#8221;);</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline4"><p>// perform the concurrent lookup</p></blockquote>
<blockquote class="codeline4"><p>AsyncDNSExample lookup = new AsyncDNSExample();</p></blockquote>
<blockquote class="codeline4"><p>List&lt;IPAddress&gt; addressList = lookup.MultiHostLookup(hosts);</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline4"><p>// write out the results</p></blockquote>
<blockquote class="codeline4"><p>foreach (IPAddress address in addressList)</p></blockquote>
<blockquote class="codeline4"><p>{</p></blockquote>
<blockquote class="codeline6"><p>Console.WriteLine(address);</p></blockquote>
<blockquote class="codeline4"><p>}</p></blockquote>
<blockquote class="codeline2"><p>}</p></blockquote>
<blockquote class="codeline0"><p>}</p></blockquote>
</blockquote>
<p><strong>Begin and End methods</strong></p>
<p>Many of .NET&#8217;s I/O classes have asynchronous versions of their synchronous methods.  For example, the <code>Read()</code> and <code>Write()</code> methods on <code><a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.io.stream.aspx" title="System.IO.Strean">System.IO.Stream</a></code> have respective <code>BeginRead()</code> and <code>BeginWrite()</code> counterparts.  <code><a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.aspx" title="System.Net.Sockets.Socket">System.Net.Sockets.Socket</a></code> has <code>BeginAccept()</code> and <code>BeginConnect()</code>.  And, in benefit of this example, <code>Dns</code> has <code>BeginGetHostAddresses()</code>.</p>
<p>All of the <code>Begin*</code> methods cause the object&#8217;s work to execute on a worker thread in the .NET thread pool.  These methods take the same parameters as their synchronous counterparts plus two additional parameters supporting the async framework.</p>
<p>For example, here&#8217;s the signature for <code>BeginGetHostAddresses()</code>:</p>
<blockquote class="codeblock">
<blockquote class="codeline0"><p>public static IAsyncResult BeginGetHostAddresses(</p></blockquote>
<blockquote class="codeline5"><p>string hostNameOrAddress,</p></blockquote>
<blockquote class="codeline5"><p>AsyncCallback requestCallback,</p></blockquote>
<blockquote class="codeline5"><p>Object state</p></blockquote>
<blockquote class="codeline0"><p>)</p></blockquote>
</blockquote>
<p>One added parameter is an <code><a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.asynccallback.aspx" title="AsyncCallback">AsyncCallback</a></code> delegate.  The delegate identifies the callback method .NET will invoke once asynchronous processing has completed.  The callback method takes a single parameter of type <code><a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.iasyncresult.aspx" title="IAsyncResult">IAsyncResult</a></code>.  The <code>IAsyncResult</code> object must be used to access the result of the asynchronous call.</p>
<p>The second added parameter is an arbitrary state object (possibly null) that may be used to coordinate between the caller and the callback.  The state object is made available to the callback method through the <code>IAsyncResult</code> parameter.  An example is included a little later.</p>
<p>For each <code>Begin*</code> call, a corresponding <code>End*</code> call must be invoked to get the results of the method.  <code>End*</code> methods block synchronously until processing has been completed.  However, when called from within the callback method, <code>End*</code> methods return immediately because, at that point, the work is known to be done.</p>
<p>Let&#8217;s take a look at how our <code>MultiHostLookup()</code> method can be implemented using the asynchronous version of <code>GetHostAddresses()</code>:</p>
<blockquote class="codeblock">
<blockquote class="codeline0"><p>public class AsyncDNSExample</p></blockquote>
<blockquote class="codeline0"><p>{</p></blockquote>
<blockquote class="codeline2"><p>public List&lt;IPAddress&gt; MultiHostLookup(List&lt;string&gt; hosts)</p></blockquote>
<blockquote class="codeline2"><p>{</p></blockquote>
<blockquote class="codeline4"><p>// we&#8217;ll fill this list with the result of the DNS lookups</p></blockquote>
<blockquote class="codeline4"><p>List&lt;IPAddress&gt; addressList = new List&lt;IPAddress&gt;();</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline4"><p>foreach (string host in hosts)</p></blockquote>
<blockquote class="codeline4"><p>{</p></blockquote>
<blockquote class="codeline6"><p>// begin an asynchronous lookup for each host</p></blockquote>
<blockquote class="codeline6"><p>Dns.BeginGetHostAddresses(</p></blockquote>
<blockquote class="codeline8"><p>host,</p></blockquote>
<blockquote class="codeline8"><p>GetHostAddressesCallback,</p></blockquote>
<blockquote class="codeline8"><p>addressList</p></blockquote>
<blockquote class="codeline6"><p>);</p></blockquote>
<blockquote class="codeline4"><p>}</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline4"><p>//</p></blockquote>
<blockquote class="codeline4"><p>// we can do additional work here while the</p></blockquote>
<blockquote class="codeline4"><p>// DNS lookups continue in parallel</p></blockquote>
<blockquote class="codeline4"><p>//</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline4"><p>lock (addressList)</p></blockquote>
<blockquote class="codeline4"><p>{</p></blockquote>
<blockquote class="codeline6"><p>// ensure all lookups have returned, otherwise wait</p></blockquote>
<blockquote class="codeline6"><p>while (addressList.Count != hosts.Count)</p></blockquote>
<blockquote class="codeline6"><p>{</p></blockquote>
<blockquote class="codeline8"><p>Monitor.Wait(addressList);</p></blockquote>
<blockquote class="codeline6"><p>}</p></blockquote>
<blockquote class="codeline4"><p>}</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline4"><p>return addressList;</p></blockquote>
<blockquote class="codeline2"><p>}</p></blockquote>
<blockquote class="codeline0"><p>}</p></blockquote>
</blockquote>
<p>This method begins by allocating the <code>List&lt;IPAddress&gt;</code> object we&#8217;ll use to return our resolved addresses.  Then, we loop over each of the host names in the hosts <code>List&lt;string&gt;</code> and call <code>BeginGetHostAddresses()</code>.  Once this loop completes, all of the DNS queries are executing in parallel.</p>
<p>Notice the first parameter to <code>BeginGetHostAddresses()</code> is a host name &#8211; just like its synchronous counterpart.  For the second parameter, we pass a reference to our callback method, <code>GetHostAddressesCallback()</code>, which is defined below.  The third parameter is our result <code>List&lt;IPAddress&gt;</code>.  This will make the <code>List</code> available to the callback method.  When each DNS query completes, the callback method can update the list with each resolved address.</p>
<p>At this point, if we wanted to, we could code other logic to execute as we wait for the queries to complete.</p>
<p>Finally, we check the length of the list of resolved IP addresses to see if it&#8217;s the same length as the list of host names.  To do this, we must first lock the address list object (after all, we don&#8217;t want our address list modified on a callback thread at the same time we&#8217;re trying to inspect it).  If the list sizes are equal, we know all lookups have completed and we can return from the method.  Otherwise, we release the lock on the address list and block until receiving notification from the callback thread.</p>
<p>It&#8217;s all pretty simple.  Now, let&#8217;s see how to implement the callback method:</p>
<blockquote class="codeblock">
<blockquote class="codeline0"><p>public class AsyncDNSExample</p></blockquote>
<blockquote class="codeline0"><p>{</p></blockquote>
<blockquote class="codeline2"><p>private void GetHostAddressesCallback(IAsyncResult result)</p></blockquote>
<blockquote class="codeline2"><p>{</p></blockquote>
<blockquote class="codeline4"><p>// This method may fail with a SocketException, particularly</p></blockquote>
<blockquote class="codeline4"><p>// if the host is not found. A more robust solution would</p></blockquote>
<blockquote class="codeline4"><p>// handle such cases.</p></blockquote>
<blockquote class="codeline4"><p>IPAddress[] addresses = Dns.EndGetHostAddresses(result);</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline4"><p>// for simplicity, we&#8217;ll take the first address</p></blockquote>
<blockquote class="codeline4"><p>IPAddress address = addresses[0];</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline4"><p>// the address list we passed in is accessbile from AsyncState</p></blockquote>
<blockquote class="codeline4"><p>List&lt;IPAddress&gt; addressList = (List&lt;IPAddress&gt;)result.AsyncState;</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline4"><p>// we need to ensure updates to the address list are threadsafe</p></blockquote>
<blockquote class="codeline4"><p>lock (addressList)</p></blockquote>
<blockquote class="codeline4"><p>{</p></blockquote>
<blockquote class="codeline6"><p>addressList.Add(address);</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline6"><p>// notify listeners that another address has been added</p></blockquote>
<blockquote class="codeline6"><p>Monitor.PulseAll(addressList);</p></blockquote>
<blockquote class="codeline4"><p>}</p></blockquote>
<blockquote class="codeline2"><p>}</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline2"><p>// this is our public method for performing multiple, concurrent</p></blockquote>
<blockquote class="codeline2"><p>// DNS requests</p></blockquote>
<blockquote class="codeline2"><p>public List&lt;IPAddress&gt; MultiHostLookup(List&lt;string&gt; hosts)</p></blockquote>
<blockquote class="codeline2"><p>{</p></blockquote>
<blockquote class="codeline4"><p>. . . .</p></blockquote>
<blockquote class="codeline2"><p>}</p></blockquote>
<blockquote class="codeline0"><p>}</p></blockquote>
</blockquote>
<p>The first thing that happens is the call to <code>EndGetHostAddresses()</code> with the <code>IAsyncResult</code> object passed in.  This call returns immediately with the result of the DNS query (it returns an array of IP addresses but, for simplicity, we&#8217;ll assume the first one is all we need).</p>
<p>Next, we get a reference to the <code>List&lt;IPAddress&gt;</code> object passed in by the <code>Begin*</code> call. This is where we&#8217;re going to save our resolved IP addresses.  However, for thread safety, we can only add our result from within a lock block.  We don&#8217;t want to be manipulating the list at the same time as another callback!</p>
<p>Finally, we pulse all threads listening on the result object.  This schedules the thread executing <code>MultiHostLookup()</code> to check if all of the results have been received.</p>
<p><strong>Conclusion</strong></p>
<p>Using asynchronous I/O can make your applications faster and your user interfaces more responsive &#8211; particularly when executing long running tasks and tasks that would otherwise leave the CPU idle. However, even with the .NET design pattern, multithreaded programming always adds to code complexity. So, only leverage this framework where performance optimization is required.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gavaghan.org/blog/2010/02/11/the-net-asynchronous-io-design-pattern/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Understanding SSL – Part 1: Certificates and Keys</title>
		<link>http://www.gavaghan.org/blog/2009/10/14/understanding-ssl-%e2%80%93-part-1-certificates-and-keys/</link>
		<comments>http://www.gavaghan.org/blog/2009/10/14/understanding-ssl-%e2%80%93-part-1-certificates-and-keys/#comments</comments>
		<pubDate>Thu, 15 Oct 2009 01:35:00 +0000</pubDate>
		<dc:creator>Mike Gavaghan</dc:creator>
				<category><![CDATA[CodeProject]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://www.gavaghan.org/blog/2009/10/14/understanding-ssl-%e2%80%93-part-1-certificates-and-keys/</guid>
		<description><![CDATA[The technology behind Secure Sockets Layer (SSL) network connections is often perceived as a bit of &#8220;black magic&#8221; – smoke and mirrors securing our Internet connections from snooping.  When banking and shopping online, even a novice user understands their browser sets up an HTTPS connection (which is simply HTTP over SSL) to protect the transaction.  [...]]]></description>
			<content:encoded><![CDATA[<p>The technology behind <a target="_blank" href="http://en.wikipedia.org/wiki/Transport_Layer_Security" title="Transport Layer Security">Secure Sockets Layer (SSL)</a> network connections is often perceived as a bit of &#8220;black magic&#8221; – smoke and mirrors securing our Internet connections from snooping.  When banking and shopping online, even a novice user understands their browser sets up an <a target="_blank" href="http://en.wikipedia.org/wiki/Https" title="HTTP Secure">HTTPS</a> connection (which is simply HTTP over SSL) to protect the transaction.  It’s easy to simply surf to a secure URL and know that, somehow, SSL is magically keeping you safe.</p>
<p>Developing software that <em>uses </em>SSL is an entirely different matter.  The simplicity quickly fades, and the developer must confront the complexities of certificate management, trust stores, handshaking, and a host of other details that must be perfectly aligned to make the secure communication work.  In Part 1, we’ll cover a very high level of SSL concepts.  In subsequent posts, we’ll take a deeper dive into making these connections happen in both Java and C#.</p>
<p><span id="more-59"></span><strong>Understanding SSL</strong></p>
<p>SSL uses <a target="_blank" href="http://en.wikipedia.org/wiki/Public_key" title="Public-key cryptography">public key/private key cryptography</a> for three purposes. The most fundamental use is to encrypt data communication between the server and client.  However, it is also used to allow the server to prove its identity to the client and prevent <a target="_blank" href="http://en.wikipedia.org/wiki/Man-in-the-middle_attack" title="Man-in-the-middle attack">man-in-the-middle attacks</a> (where a malicious intermediary intercepts messages from the client and masquerades as the intended server).</p>
<p>A third use is for allowing the client to prove its identity to the server.  <a target="_blank" href="http://en.wikipedia.org/wiki/Mutual_authentication" title="Mutual Authentication">Mutual authentication</a> is an important and powerful feature of SSL, and it’s probably underused.  For now, we’ll just focus on the semantics of server authentication.  If you understand server authentication, you’ll be well on your way to understanding client authentication on your own.</p>
<p><strong>About Certificates</strong></p>
<p>Three fundamental components are involved in setting up an SSL connection between a server and client: a certificate, a public key, and a private key.</p>
<p><a target="_blank" href="http://en.wikipedia.org/wiki/Digital_certificate" title="Digital Certificate">Digital certificates</a> are used to identify an entity.  The entity could be a person (when used for secure email), or it could be a computer (when used for SSL).  There is quite a bit of information stored in a digital certificate, but the most important part is the name of the entity it is identifying.</p>
<p>The identity, also known as the “subject”, is specified as an <a target="_blank" href="http://en.wikipedia.org/wiki/Distinguished_Name" title="Distinguished Name">X.509 distinguished name</a>.  A distinguished name contains multiple components.  For example, the distinguished name on the certificate used to setup an HTTPS connection for Amazon.com’s shopping cart check-out looks like this:</p>
<blockquote class="codeblock">
<blockquote class="codeline0"><p>CN=www.amazon.com,</p></blockquote>
<blockquote class="codeline0"><p>O=Amazon.com Inc.,</p></blockquote>
<blockquote class="codeline0"><p>L=Seattle,</p></blockquote>
<blockquote class="codeline0"><p>S=Washington,</p></blockquote>
<blockquote class="codeline0"><p>C=US</p></blockquote>
</blockquote>
<p>How do we find this information?  From Internet Explorer, browse to any secure web page (one with an <code>https://</code> protocol in the URL).  Right-click on the page and select &#8220;Properties&#8221;.  From the properties page, click the &#8220;Certificates&#8221; button.  On the &#8220;Details&#8221; tab, we can see all of the information embedded in the certificate.  By selecting the &#8220;Subject&#8221; entry, we can see the entity the certificate identifies:</p>
<p><img src="http://www.gavaghan.org/blog/wp-content/uploads/2009/10/iecertificateview1.gif" alt="Certificate Viewer in Internet Explorer" /></p>
<p>For the purposes of establishing an SSL connection to a server, the only interesting part of the distinguished name is the “Common Name” specified by the “CN” component.  This is the name the server uses to identify the domain name of the host.</p>
<p>To establish a secure connection to Amazon.com, a client first resolves the domain name <code>www.amazon.com</code>.  After the SSL connection has been initiated, one of the first things the server will do is send its digital certificate.  The client will perform a number of validation steps before determining if it will continue with the connection.</p>
<p>Most importantly, the client will compare the domain name of the server it intended to connect to (in this case, <code>www.amazon.com</code>) with the common name (the “CN” field) found in the subject’s identity on the certificate.  If these names do not match, it means the client does not trust the identity of the server (and the client will likely choose to terminate the connection).</p>
<p>Although the server name may be correct, the client must still verify the integrity of the certificate to determine if it has been forged or tampered with.  The client does this by verifying the digital signature on the certificate.  We’ll talk more about digital signatures in a moment.</p>
<p>The client will also ensure the certificate is being used within a valid time frame.  All certificates contain an “issue date” and an “expiration date”.  A certificate is considered invalid outside of that date range.</p>
<p><strong>Public and Private Keys</strong></p>
<p>Public keys and private keys are number pairs with a special relationship.  Any data encrypted with one key can be decrypted with the other.  This is known as <a target="_blank" href="http://en.wikipedia.org/wiki/Asymmetric_encryption" title="Asymmetric encryption">asymmetric encryption</a>.  The security of asymmetric encryption lies in the difficulty of cracking encrypted data even when the key used for encryption is known.</p>
<p>The server’s public key is embedded within its certificate.  The public key is freely distributed so anyone wishing to establish an encrypted channel with the server may encrypt their data using the server’s public key.  The server will decrypt this message using its private key.  For this reason, private keys are closely guarded and kept secure.</p>
<p><strong>Digital Signatures</strong></p>
<p>Just as data may be encrypted with a public key and decrypted with a private key, the reverse is also true.  Data encrypted with a private key may be decrypted with the corresponding public key.</p>
<p>This property of keys is used to ensure the integrity of a digital certificate in a process called <a target="_blank" href="http://en.wikipedia.org/wiki/Digital_signature" title="Digital signature">digital signing</a>.</p>
<p>A <a target="_blank" href="http://en.wikipedia.org/wiki/Hashing_algorithm" title="Hashing algorithm">hashing algorithm</a> (such as <a target="_blank" href="http://en.wikipedia.org/wiki/Sha1" title="SHA1 Hashing">SHA1</a> or <a target="_blank" href="http://en.wikipedia.org/wiki/MD5" title="MD5 hashing">MD5</a>) is a means of processing all of the bytes of a message and producing a numeric “hash value”.  Hash values have long been used to ensure the integrity of messages that may become corrupted during transport.  A sender will transmit a message followed by the hash value it calculated for the message it intends to send.  The receiver calculates the hash value for the message it receives.  If the receiver calculates a different hash value than the one that was sent, the receiver concludes the message was corrupted during transit (and generally asks the sender to resend).</p>
<p>A hashing algorithm may also be used to determine if a message has been forged or tampered with.  Complicating this, however, is that a malicious third party could intercept a message, modify it, and simply recalculate the hash.  Asymmetric encryption technology solves this.</p>
<p>If a message sender wants to convince a recipient that his message is authentic and has not been tampered with, he will do two things.  First, the sender will calculate a hash value for the message.  This hash value will then be encrypted using the sender’s private key (a key which the sender, and only the sender, knows).  When the client receives the message, the client decrypts the hash value using the sender’s public key.  If the message has been tampered with, or if the message has been signed with anything other than the sender’s private key, the hash values will not agree and the client will not consider the message authentic.</p>
<p><strong>Certificate Signing</strong></p>
<p>When a certificate is created, it is digitally signed.  The digital signature is used to verify the authenticity of the certificate.  In an SSL connection, the client will attempt to verify the signature on the certificate presented by the server before deciding to continue establishing the connection.</p>
<p><strong>Self-signed certificates</strong></p>
<p>The simplest certificate is a <a target="_blank" href="http://en.wikipedia.org/wiki/Self-signed_certificate" title="Self-signed Certificates">self-signed certificate</a>.  The signature on a self-signed certificate is calculated using the same private key associated with the public key found on the certificate.  In a software development environment, self-signed certificates are an easy way to build testing environments that establish SSL connections without having to deal with the time and expense of obtaining a certificate through an establish certificate authority.</p>
<p><strong>Certificate Authority signed certificates</strong></p>
<p>Certificates may also be signed by a <a target="_blank" href="http://en.wikipedia.org/wiki/Certificate_authority" title="Certificate authority">certificate authority (CA)</a>.  A CA is a trusted third party that digitally signs certificates for entities that have gone through an established vetting process.  The CA, itself, also has a certificate that can be analyzed for authenticity – and the CA’s certificate might also be signed by yet another trusted third party (in this case, the CA is known as an intermediate CA).  All of these certificates, together, form a certificate chain.  At the top of the chain is a certificate authority called a <a target="_blank" href="http://en.wikipedia.org/wiki/Root_certificate" title="Root Certificate">Root CA</a> that uses a self-signed certificate.</p>
<p>Returning to the Amazon.com example, we can examine the server certificate and see that it is not a self signed certificate – it is signed by a CA with a distinguished named of:</p>
<blockquote class="codeblock">
<blockquote class="codeline0"><p>CN=VeriSign Class 3 Secure Server CA &#8211; G2,</p></blockquote>
<blockquote class="codeline0"><p>OU=Terms of use at https://www.verisign.com/rpa (c)09,</p></blockquote>
<blockquote class="codeline0"><p>OU=VeriSign Trust Network,</p></blockquote>
<blockquote class="codeline0"><p>O=VeriSign, Inc.,</p></blockquote>
<blockquote class="codeline0"><p>C=US</p></blockquote>
</blockquote>
<p>From the certificate details tab we looked at earlier, we can find the name of the certificate issuer by selecting the &#8220;Issuer&#8221; entry:</p>
<p><img src="http://www.gavaghan.org/blog/wp-content/uploads/2009/10/iecertificateview2.gif" alt="Certificate Viewer in Internet Explorer" /></p>
<p>VeriSign is a trusted third party that issues certificates for, among other things, eCommerce applications.</p>
<p>Why is it important to have a certificate signed by a trusted third party?  It’s important because new HTTPS-based Web applications are being deployed all of the time.  In terms of browser-based, retail eCommerce applications, it’s simply impractical for users to manage a list of all of the server certificates they have decided to &#8220;trust&#8221;.  Furthermore, reliably and securely obtaining a web site&#8217;s real server certificate would be too problematic.</p>
<p>Consider a new Amazon.com customer.  When the shopping cart checkout sends Amazon.com’s certificate identifying itself as <code>www.amazon.com</code>, how does the customer know to trust the certificate?  Although the certificate may have a valid name and signature on it, how does the customer decide to trust the certificate?  If it is self-signed, it could have been signed by <em>anyone</em> – including a malicious man-in-the-middle.  What the customer needs is a reliable means of receiving Amazon’s certificate that is protected from forgery.</p>
<p>To do this, Amazon chose not to use a self-signed certificate.  Instead, for a fee, it requested that VeriSign sign its online shopping certificate.  When the customer receives Amazon.com’s certificate, she says “I trust that I have a legitimate copy of VeriSign’s CA certificate, I trust VeriSign to only sign certificates of the real domain name owners, and I can see that Amazon.com’s certificate is signed by VeriSign.  Therefore, I believe the server responding at <code>www.amazon.com</code> is truly owned and managed by the same entity owning the <code>www.amazon.com</code> domain name.”</p>
<p><strong>Where Do Trusted CA’s Come From?</strong></p>
<p>Why does the customer believe she has a legitimate copy of VeriSign’s CA certificate?  She believes this because a set of &#8220;trusted&#8221; CAs came pre-installed with her Web browser software.  Internet Explorer, Firefox, and all other leading browser vendors pre-configure their browsers to trust well known CAs such as <a target="_blank" href="http://www.verisign.com/" title="Verisign">VeriSign</a>, <a target="_blank" href="http://www.thawte.com/" title="Thawte">Thawte</a>, and <a target="_blank" href="http://www.networksolutions.com/" title="Network Solutions">Network Solutions</a>.</p>
<p>C# programs will generally access the Windows <a target="_blank" href="http://en.wikipedia.org/wiki/Cryptographic_Service_Provider" title="Windows Cryptographic Service Provider">Cryptographic Service Provider</a> for trusted certificates.  The CSP is a shared OS resource usable by any program, and is also the same trust store consulted by Internet Explorer.</p>
<p>Similarly, the Java Runtime Environment comes with a pre-configure set of trusted certificate authorities.  The collection of trusted certificates can be found at <code>[JRE_HOME]/lib/security/cacerts</code>.  The <a target="_blank" href="http://java.sun.com/javase/6/docs/technotes/tools/windows/keytool.html" title="Java keytool"><code>keytool</code></a>, a command line utility found in the SDK, can be used to inspect and manipulate this file.  The default password for the <code>cacerts</code> keystore is “<code>changeit</code>”.</p>
<p><strong>Summary</strong></p>
<p>Public key cryptography is at the heart of SSL.  While most developers are aware this technology is used to encrypt a data channel, most are unfamiliar with its use of digital signing for identity authentication and message validation.  It is the lack of understanding of these other uses that generally stymie their efforts to implement SSL.</p>
<p>Stayed tuned for more posts on the lower level details of implementing SSL technology,</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gavaghan.org/blog/2009/10/14/understanding-ssl-%e2%80%93-part-1-certificates-and-keys/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>C# Decimal and Java BigDecimal Solve Roundoff Problems</title>
		<link>http://www.gavaghan.org/blog/2007/11/06/c-decimal-and-java-bigdecimal-solve-roundoff-problems/</link>
		<comments>http://www.gavaghan.org/blog/2007/11/06/c-decimal-and-java-bigdecimal-solve-roundoff-problems/#comments</comments>
		<pubDate>Wed, 07 Nov 2007 04:49:48 +0000</pubDate>
		<dc:creator>Mike Gavaghan</dc:creator>
				<category><![CDATA[CodeProject]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://www.gavaghan.org/blog/2007/11/06/c-decimal-and-java-bigdecimal-solve-roundoff-problems/</guid>
		<description><![CDATA[Roundoff problems have been the bane of programmers since computers started handling floating point numbers. Floating point numbers are represented by a finite number of bytes. This limits the precision of numbers that may be represented - you only get so many significant digits. More subtly, however, finite length floating point numbers limit which numbers may be represented accurately. Repeating decimals (which, in a sense, require an infinite number of significant digits) cannot be represented precisely. You may only store the nearest value representable by the computer. This is the origin of annoying roundoff problems found in floating point arithmetic.

The C# and Java 4-byte float data type provides 7 significant digits of precision, while the 8-byte double type provides 15. Using the higher precision double data type helps minimize the roundoff error, but it must still be addressed.

So, when I encountered the C# 12-byte decimal data type with its 28 significant digits, and Java's arbitrary size BigDecimal data type, I figured these were simply ways of further minimizing the problem with a wider floating point type. Only after digging deeper did I realize that the implementation behind both of these data types is a stroke of genius.]]></description>
			<content:encoded><![CDATA[<p>Roundoff problems have been the bane of programmers since computers started handling floating point numbers. Floating point numbers are represented by a finite number of bytes. This limits the precision of numbers that may be represented &#8211; you only get so many significant digits. More subtly, however, finite length floating point numbers limit <em>which</em> numbers may be represented accurately. Repeating decimals (which, in a sense, require an infinite number of significant digits) cannot be represented precisely. You may only store the nearest value representable by the computer. This is the origin of annoying roundoff problems found in floating point arithmetic.</p>
<p>The C# and Java 4-byte <code>float</code> data type provides 7 significant digits of precision, while the 8-byte <code>double</code> type provides 15. Using the higher precision <code>double</code> data type helps minimize the roundoff error, but it must still be addressed.</p>
<p>So, when I encountered the C# 12-byte <code>decimal</code> data type with its 28 significant digits, and Java&#8217;s arbitrary size <code>BigDecimal</code> data type, I figured these were simply ways of further minimizing the problem with a wider floating point type. Only after digging deeper did I realize that the implementation behind both of these data types is a stroke of genius.</p>
<p><span id="more-18"></span></p>
<p><strong>The need for precision</strong></p>
<p>In scientific applications, inexact representation is a non-issue. Whether you&#8217;re measuring the temperature on the Sun or the diameter of an atom, things like numeric magnitude matter more than accuracy out to the 17th decimal point. In graphical applications, you&#8217;re probably rounding off to the nearest pixel, anyway. In general, computers provide floating point precision that greatly exceeds any practical need.</p>
<p>You get into trouble, however, with financial applications. Even when you&#8217;re dealing with million dollar transactions, your debits and credits must match exactly. Off by a penny? You&#8217;ll drive the accountants nuts!</p>
<p>Consider this C# example. Below, pretend we&#8217;ve got a bank account with $100,000 and we withdraw $99,999.67. How much money is left? $0.33, right? Let&#8217;s see what C# calculates:</p>
<blockquote class="codeblock">
<blockquote class="codeline0"><p>using System;</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline0"><p>namespace FloatingPoint</p></blockquote>
<blockquote class="codeline0"><p>{</p></blockquote>
<blockquote class="codeline1"><p>public class SubtractionRoundoff</p></blockquote>
<blockquote class="codeline1"><p>{</p></blockquote>
<blockquote class="codeline2"><p>static void Main()</p></blockquote>
<blockquote class="codeline2"><p>{</p></blockquote>
<blockquote class="codeline3"><p>float floatValue = 100000;</p></blockquote>
<blockquote class="codeline3"><p>double doubleValue = 100000f;</p></blockquote>
<blockquote class="codeline3"><p>decimal decimalValue = 100000m;</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline3"><p>floatValue -= 99999.67f;</p></blockquote>
<blockquote class="codeline3"><p>doubleValue -= 99999.67;</p></blockquote>
<blockquote class="codeline3"><p>decimalValue -= 99999.67m;</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline3"><p>Console.WriteLine(&#8220;float result = &#8221; + floatValue);</p></blockquote>
<blockquote class="codeline3"><p>Console.WriteLine(&#8220;double result = &#8221; + doubleValue);</p></blockquote>
<blockquote class="codeline3"><p>Console.WriteLine(&#8220;decimal result = &#8221; + decimalValue);</p></blockquote>
<blockquote class="codeline2"><p>}</p></blockquote>
<blockquote class="codeline1"><p>}</p></blockquote>
<blockquote class="codeline0"><p>}</p></blockquote>
</blockquote>
<p>If you&#8217;ve ever written floating point code, you can probably predict the first two lines:</p>
<blockquote class="codeouttake"><p>float result = 0.328125<br />
double result = 0.330000000001746<br />
decimal result = 0.33</p></blockquote>
<p>Both the <code>float</code> and <code>double</code> calculations have roundoff error, even though both perform calculations within the limits of their significant digits. The integer value 100,000 can be represented precisely, but neither <code>float</code> nor <code>double</code> can precisely represent the fractional part of 99,999.67. &#8220;.67&#8243; would require an infinitely repeating series of bytes. C# and Java must truncate the bytes to the width of the data-type. This representational error then appears after the subtraction operation.</p>
<p>But, how come the <code>decimal</code> type nailed it &#8211; exactly? Shouldn&#8217;t the <code>decimal</code> type still have some error, albeit with far less magnitude than the <code>double</code>? Java <code>BigDecimal</code> will hit it on the nose, too. The reason for this is a thing of beauty.</p>
<p><strong>How floating point numbers are represented</strong></p>
<p>The gory details of floating point representation is a bit much to cover here, especially when it has already seen a great discussion in Bill Venner&#8217;s article <a target="_blank" href="http://www.javaworld.com/javaworld/jw-10-1996/jw-10-hood.html" title="Floating-point Arithmetic">Floating-point Arithmetic</a>. Although the article is Java-specific, the basic details are completely valid for C#. It&#8217;s a must read if words like &#8220;mantissa&#8221; and &#8220;radix&#8221; are unfamiliar to you.</p>
<p>Floating point numbers are essentially represented as a fixed length integer (the &#8220;mantissa&#8221;) combined with a scale that shifts the decimal point left or right (can we still call it a &#8220;decimal&#8221; point when we&#8217;re dealing in base 2?) This shifting is determined by a radix (the &#8220;base&#8221; of the representation) raised to an exponent.</p>
<p><code>float</code> and <code>decimal</code> both use a radix of 2. Hence, the number 3.125 could be represented with an integral mantissa of 25 and an exponent of -3:</p>
<blockquote><p>25 * 2<sup>-3</sup> = 3.125</p></blockquote>
<p>Okay, remember this tidbit from high school? How can you tell if the decimal representation of a fraction will produce a repeating decimal? If the denominator has any factors other than 2 or 5, the decimal representation will repeat infinitely. So, fractions like 1/2, 2/5, and 3/10 may be represented exactly as 0.5, 0.4, and 0.3. But, 1/3 is a infinite series of 3s (0.33333 . . .).</p>
<p>When representing fractions in binary, the representation of a fraction repeats infinitely if the denominator has factors other than only 2. So, 1/2 and 3/4 are fine, but not 1/10 (the number 10 includes 5 as a factor). So, the non-repeating decimal 0.1 cannot be represented precisely in a computer.</p>
<p>In a typical application, we enter numbers in human usable form &#8211; base 10. But, the computer makes an inexact conversion to base 2, performs some arithmetic on the inexact numbers, and then converts the result back to base 10. No wonder roundoff problems occur!</p>
<p><strong>How <code>decimal</code> and <code>BigDecimal</code> are different</strong></p>
<p>Don&#8217;t fall asleep on me now, I&#8217;m working up to the grand finale!</p>
<p>Floating point numbers have traditionally been represented in base 2 because that&#8217;s a natural representation for computers. The arithmetic is fast and efficient.</p>
<p>The genius in <code>decimal</code> and <code>BigDecimal</code> is they both use base 10 internally for both storage and arithmetic. When you enter 0.1 in an application, you get precisely 0.1. These new floating point types understand numbers the same way you do, so there&#8217;s no inexact internal representation. You can add and subtract financial values all day and not lose a thing. No need to round off string values to the nearest penny.</p>
<p>What about performance? The answer here is predictable: base 10 arithmetic is slow &#8211; very slow. It has to be done in software, whereas base 2 floating point arithmetic can be offloaded to a specialized floating point processor. For hard performance comparison numbers, check out Wesner Moise&#8217;s <a target="_blank" href="http://wesnerm.blogs.com/net_undocumented/2004/03/decimal_perform.html" title="Decimal Performance">Decimal Performance</a>. But, for most financial apps, the performance hit is a non-issue &#8211; especially when compared against the cost of programmer&#8217;s trying to correct roundoff errors manually.</p>
<p>Some calculations will still result in repeating decimals. Calculating 1/3 will still result in a repeating decimal. But, these issues have always needed a business solution. On interest calculations, banks have <em>always</em> had to address whether fractional pennies in interest calculations round to the benefit of the bank or the depositor. Those problems are easily handled, but esoteric problems introduced in the black magic of the CPU aren&#8217;t. Using <code>decimal</code> and <code>BigDecimal</code> for financial calculations allows programmers to worry only about the easy problems.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gavaghan.org/blog/2007/11/06/c-decimal-and-java-bigdecimal-solve-roundoff-problems/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>NHibernate in a Medium Trust Environment</title>
		<link>http://www.gavaghan.org/blog/2007/08/21/nhibernate-in-a-medium-trust-environment/</link>
		<comments>http://www.gavaghan.org/blog/2007/08/21/nhibernate-in-a-medium-trust-environment/#comments</comments>
		<pubDate>Tue, 21 Aug 2007 17:15:11 +0000</pubDate>
		<dc:creator>Mike Gavaghan</dc:creator>
				<category><![CDATA[CodeProject]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://www.gavaghan.org/blog/2007/08/21/nhibernate-in-a-medium-trust-environment/</guid>
		<description><![CDATA[I've recently started experimenting with NHibernate – the C#/.NET version of the Hibernate O/R matpping tool that was originally developed for Java. The Java version is very powerful, and I'm a huge fan of it. The C#/.NET version is, for the most part, a straight port of the Java code base (and an ugly port, in some ways). Nevertheless, it appears to be just as robust as its predecessor.

Be warned, however, that the NHibernate DLLs require a high level of trust in the ASP.NET environment they're deployed to. I spent an entire weekend beating my head against a wall trying to get a simple app up on my GoDaddy account. I suspect NHibernate probably wasn't designed with a medium trust environment in mind. I was able to make a few tweaks to get the code running with fewer permissions requirements. However, the permissions required to enable dynamic proxies – a fundamental part of the NHibernate architecture – are non-negotiable.

I learned from GoDaddy tech support that their Deluxe Windows plan, a shared host environment, simply doesn’t allow those permissions. I'd need to upgrade to a dedicated server, and that's just a little too pricey for an environment simply for experimentation.  I was able to get NHibernate working without any hacks at Webhost4life, but I thought I'd share what I tried first at GoDaddy just to help you understand the permissions implications and how you might need to address them on your own projects.
]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve recently started experimenting with <a target="_blank" href="http://www.hibernate.org/343.html" title="NHibernate for .NET">NHibernate</a> – the C#/.NET version of the <a target="_blank" href="http://www.hibernate.org/" title="Relational Persistence for Java and .NET">Hibernate</a> O/R matpping tool that was originally developed for Java. The Java version is very powerful, and I&#8217;m a huge fan of it. The C#/.NET version is, for the most part, a straight port of the Java code base (and an ugly port, in some ways). Nevertheless, it appears to be just as robust as its predecessor.</p>
<p>Be warned, however, that the NHibernate DLLs require a high level of trust in the ASP.NET environment they&#8217;re deployed to. I spent an entire weekend beating my head against a wall trying to get a simple app up on my GoDaddy account. I suspect NHibernate probably wasn&#8217;t designed with a medium trust environment in mind. I was able to make a few tweaks to get the code running with fewer permissions requirements. However, the permissions required to enable dynamic proxies – a fundamental part of the NHibernate architecture – are non-negotiable.</p>
<p>I learned from GoDaddy tech support that their Deluxe Windows plan, a shared host environment, simply doesn’t allow those permissions. I&#8217;d need to upgrade to a dedicated server, and that&#8217;s just a little too pricey for an environment simply for experimentation. I was able to get NHibernate working <em>without</em> any hacks at <a target="_blank" href="http://www.webhost4life.com/" title="Webhost4life">Webhost4life</a>, but I thought I&#8217;d share what I tried first at GoDaddy just to help you understand the permissions implications if you&#8217;re in a medium trust environment &#8212; and how you might need to address them on your own projects.</p>
<p align="center"><a href="http://www.WebHost4Life.com/default.asp?refid=mgavagha"><br />
<img border="0" width="468" src="http://www.WebHost4Life.com/images/banner2.gif" alt="Join WebHost4Life.com" height="60" /></a></p>
<p align="left"><span id="more-38"></span></p>
<p><strong>Step 1 – Allow Partially Trusted Callers</strong></p>
<p>Right off the bat, ASP.NET was complaining that my domain object assembly didn&#8217;t allow partially trusted callers:</p>
<blockquote class="codeouttake"><p>[SecurityException: That assembly does not allow partially trusted callers.]</p></blockquote>
<p>This is because NHibernate, during its startup configuration, references the persistent classes it&#8217;s configured to manage. The callbacks were denied because partially trusted callers are not permitted unless explicitly enabled. So, I needed to enable partially trusted callers in my own domain object DLL by adding this attribute to the assembly:</p>
<blockquote class="codeblock">
<blockquote class="codeline0"><p>[assembly: AllowPartiallyTrustedCallers()]</p></blockquote>
</blockquote>
<p><strong>Step 2 &#8211; Tweak NHibernate.Mapping.Attributes</strong></p>
<p>I use <a target="_blank" href="http://www.hibernate.org/hib_docs/nhibernate/html/mapping-attributes.html" title="NHibernate.Mapping.Attributes">NHibernate.Mapping.Attributes</a> to map my domain objects to my database tables. It&#8217;s a lot cleaner and easier to maintain than the old fashioned XML configuration files. Unfortunately, this add-on library to NHibernate doesn&#8217;t explicitly allow partially trusted callers. So, we again run into the problem of security exceptions when other assemblies attempt to invoke the NHibernate.Mapping.Attributes library.</p>
<p>Fortunately, the NHibernate library comes with a source code download (isn&#8217;t open source software great?). I simply added the <code>AllowPartiallyTrustedCallers</code> attribute to the NHibernate.Mapping.Attributes assembly and rebuilt the DLL using the solution and projects provided. <em>Voila!</em></p>
<p>The next roadblock, however, was this exception coming out of NHibernate.Mapping.Attributes:</p>
<blockquote class="codeouttake"><p>SecurityException: Request for the permission of type &#8216;System.Security.Permissions.FileIOPermission</p></blockquote>
<p>This simply turns out to be a quirk in how the <code>HbwWriter</code> class was implemented. The class attempts to construct a &#8220;Type Name&#8221; + &#8220;Assembly name&#8221; string like this:</p>
<blockquote class="codeblock">
<blockquote class="codeline0"><p>string typeName = type.FullName + &#8220;, &#8221; + type.Assembly.GetName().Name;</p></blockquote>
</blockquote>
<p>The problem here is that the <code>Assmbly.GetName()</code> method requires <code>FileIOPermission</code> in order to return the assembly path. It&#8217;s not necessary for <code>HbmWriter</code> to get the assembly name in this fashion, so I refactored this code to build the string in a way that doesn&#8217;t require <code>FileIOPermission</code>:</p>
<blockquote class="codeblock">
<blockquote class="codeline0"><p>string assemblyName = type.Assembly.FullName;</p></blockquote>
<blockquote class="codeline0"><p>int comma = assemblyName.IndexOf(&#8220;,&#8221;);</p></blockquote>
<blockquote class="codeline0"><p>assemblyName = assemblyName.Substring(0, comma);</p></blockquote>
<blockquote class="codeline0"><p>string typeName = type.FullName + &#8220;, &#8221; + assemblyName;</p></blockquote>
</blockquote>
<p><strong>Step 3 &#8211; Get Stymied By DynamicMethod</strong></p>
<p>I solved the problem of partially trusted callers and an unnecessary dependence on <code>FileIOPermission</code>, but the next problem I encountered was a showstopper.</p>
<p>In the core NHibernate library, the <code>ReflectionOptimizer</code> class attempts to instantiate <code>DynamicMethod</code> instances to hang persistence-enabled methods off of your domain objects:</p>
<blockquote class="codeblock">
<blockquote class="codeline0"><p>new DynamicMethod(string.Empty, returnType, argumentTypes, owner, canSkipChecks);</p></blockquote>
</blockquote>
<p>After decompiling the .NET SDK, I discovered this unavoidable permission demand in the DynamicMethod constructor:</p>
<blockquote class="codeblock">
<blockquote class="codeline0"><p>new ReflectionPermission(ReflectionPermissionFlag.ReflectionEmit).Demand();</p></blockquote>
</blockquote>
<p>If <code>ReflectionEmit</code> is denied, this line of code throws a security exception. Alas, it&#8217;s not permitted in the GoDaddy environment I was using. It&#8217;s also nothing that can be reasonably worked around because dynamic proxies are an integral part of how NHibernate is built.</p>
<p>Everything works fine when I deploy to my new <a target="_blank" href="http://www.webhost4life.com/" title="Webhost4life">Webhost4life</a> account because the shared environment permissions are more lax. So, the lesson learned is to scrutinize the trust level of your target platform before making an investment in NHibernate.</p>
<p>It&#8217;s unfortunate that most ASP.NET hosting providers aren&#8217;t explicit about the trust levels they provide in their different environments. I also discovered that their level one support techs generally can&#8217;t provide that information, either. Your best bet is to rely on the experience of others and to share your own.</p>
<p align="center"><a href="http://www.WebHost4Life.com/default.asp?refid=mgavagha"><br />
<img border="0" width="468" src="http://www.WebHost4Life.com/images/banner2.gif" alt="Join WebHost4Life.com" height="60" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.gavaghan.org/blog/2007/08/21/nhibernate-in-a-medium-trust-environment/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>C#, GPS Receivers, and Geocaching: Vincenty&#8217;s Formula</title>
		<link>http://www.gavaghan.org/blog/2007/08/06/c-gps-receivers-and-geocaching-vincentys-formula/</link>
		<comments>http://www.gavaghan.org/blog/2007/08/06/c-gps-receivers-and-geocaching-vincentys-formula/#comments</comments>
		<pubDate>Mon, 06 Aug 2007 11:57:54 +0000</pubDate>
		<dc:creator>Mike Gavaghan</dc:creator>
				<category><![CDATA[CodeProject]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://www.gavaghan.org/blog/2007/08/06/c-gps-receivers-and-geocaching-vincentys-formula/</guid>
		<description><![CDATA[Vincenty's Formula is an iterative solution for calculating the distance and direction between two points along the surface of Earth. For clarity, I've stripped out portions of the code I've put up for discussion, but you can download the entire C# source code from here.

Several years ago, I stumbled on a great pastime called "geocaching." It's a worldwide treasure hunting game where participants use handheld GPS receivers to find hidden "caches" - small boxes filled with prizes, trinkets, and "travel bugs". The caches are hidden by other participants who post nothing more than the latitude and longitude on a website like Geocaching.com. My children and I have had a blast. It's a great way for a grown man to justify playing in the woods (and buying an expensive gadget!) under the pretense of "playing with the kids." With over 420,000 caches in 222 countries on all continents (including Antarctica!) there are bound to be several near you.]]></description>
			<content:encoded><![CDATA[<p>Vincenty&#8217;s Formula is an iterative solution for calculating the distance and direction between two points along the surface of Earth. For clarity, I&#8217;ve stripped out portions of the code I&#8217;ve put up for discussion, but you can <a href="http://www.gavaghan.org/blog/free-source-code/geodesy-library-vincentys-formula/" title="C# Geodesy Vincenty's Formula">download the entire C# source code from here</a>. If you prefer Java, please see <a href="http://www.gavaghan.org/blog/2007/11/16/java-gps-receivers-and-geocaching-vincentys-formula/">the Java version of this discussion.</a></p>
<p>Several years ago, I stumbled on a great pastime called &#8220;<a target="_blank" href="http://en.wikipedia.org/wiki/Geocaching" title="Geocaching">geocaching</a>.&#8221; It&#8217;s a worldwide treasure hunting game where participants use handheld <a target="_blank" href="http://en.wikipedia.org/wiki/Gps_receiver" title="GPS Receiver">GPS receivers</a> to find hidden &#8220;caches&#8221; &#8211; small boxes filled with prizes, trinkets, and &#8220;<a target="_blank" href="http://en.wikipedia.org/wiki/Travel_Bug" title="Travel Bugs">travel bugs</a>&#8220;. The caches are hidden by other participants who post nothing more than the latitude and longitude on a website like <a target="_blank" href="http://www.geocaching.com/" title="Geocaching.com">Geocaching.com</a>. My children and I have had a blast. It&#8217;s a great way for a grown man to justify playing in the woods (and buying an expensive gadget!) under the pretense of &#8220;playing with the kids.&#8221; With over 420,000 caches in 222 countries on all continents (including Antarctica!) there are bound to be several near you.</p>
<p><span id="more-27"></span>Want to know more? Check out this <a href="http://www.gavaghan.org/blog/uploads/geocaching/Geocaching.mpg" onclick="javascript:urchinTracker('/outgoing/geocaching_video');" title="Josh Gavaghan Geocaching">video of my son on a geocache hunt</a>.</p>
<p>So, being the true geek I am, I coded up a bunch of applications to record where we&#8217;ve been, where we&#8217;d like to go, and interesting waypoints along the way. Often, I&#8217;d ask the question &#8220;How far is it for here to there?&#8221;</p>
<p><strong>The Geodetic Inverse Problem</strong></p>
<p>&#8220;How far?&#8221; turns out to be a fairly complicated question. For centuries, humankind has known Earth is round &#8211; but everything else about the shape of Earth is less understood. In fact, an entire field called &#8220;<a target="_blank" href="http://en.wikipedia.org/wiki/Geodesy" title="Geodesy and geodetics">geodesy</a>&#8220;, or &#8220;geodetics,&#8221; focuses on understanding the shape of Earth.</p>
<p>If we assume Earth is a perfect sphere, the math is easy. Given the size of Earth and the latitude and longitude of two points, we can quickly calculate the &#8220;<a target="_blank" href="http://en.wikipedia.org/wiki/Great_circle" title="Great circle">great circle</a>&#8221; distance and direction from one point to the next.</p>
<p>But, Earth is <em>not</em> a perfect sphere. It&#8217;s an irregular shape geodesists call the &#8220;geoid&#8221;. Because precise measurements of the geoid and the corresponding distance calculations would be impractical, the geoid is often modeled as an ellipsoid &#8211; an object resembling a sphere but slightly flattened at the poles. It&#8217;s still an inexact model, but it performs far better than the spherical model.</p>
<p>That&#8217;s where the math gets hard. The Geodetic Inverse Problem &#8211; finding the distance and direction from one point to another along an ellipsoid &#8211; does not have a closed form solution. However, in 1975, <a target="_blank" href="http://en.wikipedia.org/wiki/Thaddeus_Vincenty" title="Thaddeus Vincenty">Thaddeus Vincenty</a> developed an extremely accurate iterative solution for which he won the Department of Commerce Medal for Meritorious Service. If you want to sprain your brain, <a target="_blank" href="http://www.ngs.noaa.gov/PUBS_LIB/inverse.pdf" onclick="javascript:urchinTracker('/outgoing/vincentys_formulae');" title="Vincenty Formulae">you can read the full publication of his solution</a>.</p>
<p>Or, you can just download <a href="http://www.gavaghan.org/blog/free-source-code/geodesy-library-vincentys-formula/" title="C# Geodesy Vincenty's Formula">my C# implementation of Vincenty&#8217;s Formula</a>.</p>
<p><strong>Building the code</strong></p>
<p>I&#8217;ll start with a convenient type for encapsulating angles. We&#8217;ll need this for latitudes and longitudes. It might seem to be overkill since we could simply uses <code>double</code> instead of a custom <code>Angle</code> type, but humans think in &#8220;degrees&#8221; while computers do math in &#8220;radians&#8221;. Rather than risk confusion and sprinkle conversion code throughout, I thought this would be easier:</p>
<blockquote class="codeblock">
<blockquote class="codeline0"><p>namespace Gavaghan.Geodesy</p></blockquote>
<blockquote class="codeline0"><p>{</p></blockquote>
<blockquote class="codeline1"><p>public struct Angle : IComparable&lt;Angle&gt;</p></blockquote>
<blockquote class="codeline1"><p>{</p></blockquote>
<blockquote class="codeline2"><p>private const double PiOver180 = Math.PI / 180.0;</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline2"><p>private double mDegrees;</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline2"><p>static public readonly Angle Zero = new Angle(0);</p></blockquote>
<blockquote class="codeline2"><p>static public readonly Angle Angle180 = new Angle(180);</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline2"><p>public Angle(double degrees)</p></blockquote>
<blockquote class="codeline2"><p>{</p></blockquote>
<blockquote class="codeline3"><p>mDegrees = degrees;</p></blockquote>
<blockquote class="codeline2"><p>}</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline2"><p>public double Degrees</p></blockquote>
<blockquote class="codeline2"><p>{</p></blockquote>
<blockquote class="codeline3"><p>get { return mDegrees; }</p></blockquote>
<blockquote class="codeline3"><p>set { mDegrees = value; }</p></blockquote>
<blockquote class="codeline2"><p>}</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline2"><p>public double Radians</p></blockquote>
<blockquote class="codeline2"><p>{</p></blockquote>
<blockquote class="codeline3"><p>get { return mDegrees * PiOver180; }</p></blockquote>
<blockquote class="codeline3"><p>set { mDegrees = value / PiOver180; }</p></blockquote>
<blockquote class="codeline2"><p>}</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline2"><p>//</p></blockquote>
<blockquote class="codeline2"><p>// Equals, IComparable&lt;T&gt; implementation and</p></blockquote>
<blockquote class="codeline2"><p>// comparison operators omitted for clarity.</p></blockquote>
<blockquote class="codeline2"><p>// See full source code download</p></blockquote>
<blockquote class="codeline2"><p>//</p></blockquote>
<blockquote class="codeline1"><p>}</p></blockquote>
<blockquote class="codeline0"><p>}</p></blockquote>
</blockquote>
<p>Some critical portions of the <code>Angle</code> type above are omitted for clarity &#8211; like all of the comparison operators. You can check out the complete implementation in <a href="http://www.gavaghan.org/blog/free-source-code/geodesy-library-vincentys-formula/" title="C# Geodesy Vincenty Formula">the source code download</a>.</p>
<p>Next, we have a class that encapsulates a location on an ellipsoid.</p>
<blockquote class="codeblock">
<blockquote class="codeline0"><p>namespace Gavaghan.Geodesy</p></blockquote>
<blockquote class="codeline0"><p>{</p></blockquote>
<blockquote class="codeline1"><p>public struct GlobalCoordinates : IComparable&lt;GlobalCoordinates&gt;</p></blockquote>
<blockquote class="codeline1"><p>{</p></blockquote>
<blockquote class="codeline2"><p>private Angle mLatitude;</p></blockquote>
<blockquote class="codeline2"><p>private Angle mLongitude;</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline2"><p>public GlobalCoordinates(Angle latitude, Angle longitude)</p></blockquote>
<blockquote class="codeline2"><p>{</p></blockquote>
<blockquote class="codeline3"><p>mLatitude = latitude;</p></blockquote>
<blockquote class="codeline3"><p>mLongitude = longitude;</p></blockquote>
<blockquote class="codeline2"><p>}</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline2"><p>public Angle Latitude</p></blockquote>
<blockquote class="codeline2"><p>{</p></blockquote>
<blockquote class="codeline3"><p>get { return mLatitude; }</p></blockquote>
<blockquote class="codeline3"><p>set { mLatitude = value; }</p></blockquote>
<blockquote class="codeline2"><p>}</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline2"><p>public Angle Longitude</p></blockquote>
<blockquote class="codeline2"><p>{</p></blockquote>
<blockquote class="codeline3"><p>get { return mLongitude; }</p></blockquote>
<blockquote class="codeline3"><p>set { mLongitude = value; }</p></blockquote>
<blockquote class="codeline2"><p>}</p></blockquote>
<blockquote class="codeline1"><p>}</p></blockquote>
<blockquote class="codeline0"><p>}</p></blockquote>
</blockquote>
<p>Negative latitudes are in the southern hemisphere, and negative longitudes are in the western hemisphere. Once again, the <code>IComparable&lt;T&gt;</code> implementation is omitted for clarity.</p>
<p>Now, we start getting to the fun part. The next type encapsulates the &#8220;geodetic curve.&#8221;</p>
<blockquote class="codeblock">
<blockquote class="codeline0"><p>namespace Gavaghan.Geodesy</p></blockquote>
<blockquote class="codeline0"><p>{</p></blockquote>
<blockquote class="codeline1"><p>public struct GeodeticCurve</p></blockquote>
<blockquote class="codeline1"><p>{</p></blockquote>
<blockquote class="codeline2"><p>private readonly double mEllipsoidalDistance;</p></blockquote>
<blockquote class="codeline2"><p>private readonly Angle mAzimuth;</p></blockquote>
<blockquote class="codeline2"><p>private readonly Angle mReverseAzimuth;</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline2"><p>public GeodeticCurve(double ellipsoidalDistance,</p></blockquote>
<blockquote class="codeline4"><p>Angle azimuth, Angle reverseAzimuth)</p></blockquote>
<blockquote class="codeline2"><p>{</p></blockquote>
<blockquote class="codeline3"><p>mEllipsoidalDistance = ellipsoidalDistance;</p></blockquote>
<blockquote class="codeline3"><p>mAzimuth = azimuth;</p></blockquote>
<blockquote class="codeline3"><p>mReverseAzimuth = reverseAzimuth;</p></blockquote>
<blockquote class="codeline2"><p>}</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline2"><p>public double EllipsoidalDistance</p></blockquote>
<blockquote class="codeline2"><p>{</p></blockquote>
<blockquote class="codeline3"><p>get { return mEllipsoidalDistance; }</p></blockquote>
<blockquote class="codeline2"><p>}</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline2"><p>public Angle Azimuth</p></blockquote>
<blockquote class="codeline2"><p>{</p></blockquote>
<blockquote class="codeline3"><p>get { return mAzimuth; }</p></blockquote>
<blockquote class="codeline2"><p>}</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline2"><p>public Angle ReverseAzimuth</p></blockquote>
<blockquote class="codeline2"><p>{</p></blockquote>
<blockquote class="codeline3"><p>get { return mReverseAzimuth; }</p></blockquote>
<blockquote class="codeline2"><p>}</p></blockquote>
<blockquote class="codeline1"><p>}</p></blockquote>
<blockquote class="codeline0"><p>}</p></blockquote>
</blockquote>
<p>A &#8220;geodetic curve&#8221; is the solution we&#8217;re looking for. It describes how to get from one point on an ellipsoid to another. The ellipsoidal distance is the distance, in meters, between the two points along the surface of the ellipsoid. The azimuth is the direction of travel from the starting point to the ending point. The reverse azimuth, of course, is the direction back from the endpoint (which isn&#8217;t necessarily a 180 degree turn on an ellipsoid).</p>
<p>The final input we need to Vincenty&#8217;s Formula is an ellipsoid. We hold onto four parameters of an ellipsoid: the length of each semi-axis (in meters), the flattening ratio, and the inverse of the flattening ratio. Technically, we only need the length of one semi-axis and any one of the other three parameters. We&#8217;ll record all four for convenience.</p>
<blockquote class="codeblock">
<blockquote class="codeline0"><p>namespace Gavaghan.Geodesy</p></blockquote>
<blockquote class="codeline0"><p>{</p></blockquote>
<blockquote class="codeline1"><p>public struct Ellipsoid</p></blockquote>
<blockquote class="codeline1"><p>{</p></blockquote>
<blockquote class="codeline2"><p>private readonly double mSemiMajorAxis;</p></blockquote>
<blockquote class="codeline2"><p>private readonly double mSemiMinorAxis;</p></blockquote>
<blockquote class="codeline2"><p>private readonly double mFlattening;</p></blockquote>
<blockquote class="codeline2"><p>private readonly double mInverseFlattening;</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline2"><p>private Ellipsoid(double semiMajor, double semiMinor,</p></blockquote>
<blockquote class="codeline6"><p>double flattening, double inverseFlattening)</p></blockquote>
<blockquote class="codeline2"><p>{</p></blockquote>
<blockquote class="codeline3"><p>mSemiMajorAxis = semiMajor;</p></blockquote>
<blockquote class="codeline3"><p>mSemiMinorAxis = semiMinor;</p></blockquote>
<blockquote class="codeline3"><p>mFlattening = flattening;</p></blockquote>
<blockquote class="codeline3"><p>mInverseFlattening = inverseFlattening;</p></blockquote>
<blockquote class="codeline2"><p>}</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline2"><p>static public readonly Ellipsoid WGS84</p></blockquote>
<blockquote class="codeline5"><p>= FromAAndInverseF(6378137.0, 298.257223563);</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline2"><p>static public readonly Ellipsoid GRS80</p></blockquote>
<blockquote class="codeline5"><p>= FromAAndInverseF(6378137.0, 298.257222101);</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline2"><p>static public readonly Ellipsoid GRS67</p></blockquote>
<blockquote class="codeline5"><p>= FromAAndInverseF(6378160.0, 298.25);</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline2"><p>static public readonly Ellipsoid ANS</p></blockquote>
<blockquote class="codeline5"><p>= FromAAndInverseF(6378160.0, 298.25);</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline2"><p>static public readonly Ellipsoid Clarke1880</p></blockquote>
<blockquote class="codeline5"><p>= FromAAndInverseF(6378249.145, 293.465);</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline2"><p>static public Ellipsoid FromAAndInverseF(double semiMajor,</p></blockquote>
<blockquote class="codeline6"><p>double inverseFlattening)</p></blockquote>
<blockquote class="codeline2"><p>{</p></blockquote>
<blockquote class="codeline3"><p>double f = 1.0 / inverseFlattening;</p></blockquote>
<blockquote class="codeline3"><p>double b = (1.0 &#8211; f) * semiMajor;</p></blockquote>
<blockquote class="codeline3"><p>return new Ellipsoid(semiMajor, b, f, inverseFlattening);</p></blockquote>
<blockquote class="codeline2"><p>}</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline2"><p>public double SemiMajorAxis</p></blockquote>
<blockquote class="codeline2"><p>{</p></blockquote>
<blockquote class="codeline3"><p>get { return mSemiMajorAxis; }</p></blockquote>
<blockquote class="codeline2"><p>}</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline2"><p>public double SemiMinorAxis</p></blockquote>
<blockquote class="codeline2"><p>{</p></blockquote>
<blockquote class="codeline3"><p>get { return mSemiMinorAxis; }</p></blockquote>
<blockquote class="codeline2"><p>}</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline2"><p>public double Flattening</p></blockquote>
<blockquote class="codeline2"><p>{</p></blockquote>
<blockquote class="codeline3"><p>get { return mFlattening; }</p></blockquote>
<blockquote class="codeline2"><p>}</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline2"><p>public double InverseFlattening</p></blockquote>
<blockquote class="codeline2"><p>{</p></blockquote>
<blockquote class="codeline3"><p>get { return mInverseFlattening; }</p></blockquote>
<blockquote class="codeline2"><p>}</p></blockquote>
<blockquote class="codeline1"><p>}</p></blockquote>
<blockquote class="codeline0"><p>}</p></blockquote>
</blockquote>
<p>Generally, you won&#8217;t need to specify ellipsoid parameters. The <code>Ellipsoid</code> type has a number of static instances that define &#8220;reference ellipsoids&#8221;. Reference ellipsoids represent some organization&#8217;s consensus on the &#8220;best&#8221; ellipsoidal parameters to use to model Earth. Two of the most widely accepted reference ellipsoids are defined above: WGS84 (the <a target="_blank" href="http://en.wikipedia.org/wiki/WGS84" title="1984 World Geodetic System">1984 World Geodetic System</a>) and GRS80 (the <a target="_blank" href="http://en.wikipedia.org/wiki/GRS80" title="1980 Geodetic Reference System">1980 Geodetic Reference System</a>).</p>
<p>Finally, we have the class that actually implements Vincenty&#8217;s Formula to solve the Geodetic Inverse Problem given a reference ellipsoid and two sets of global coordinates (equation numbers in comments relate directly to <a target="_blank" href="http://www.ngs.noaa.gov/PUBS_LIB/inverse.pdf" onclick="javascript:urchinTracker('/outgoing/vincentys_formulae');" title="Vincenty's Formulae">Vincenty&#8217;s publication</a>):</p>
<blockquote class="codeblock">
<blockquote class="codeline0"><p>using System;</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline0"><p>namespace Gavaghan.Geodesy</p></blockquote>
<blockquote class="codeline0"><p>{</p></blockquote>
<blockquote class="codeline1"><p>public class GeodeticCalculator</p></blockquote>
<blockquote class="codeline1"><p>{</p></blockquote>
<blockquote class="codeline2"><p>private const double TwoPi = 2.0 * Math.PI;</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline2"><p>public GeodeticCurve CalculateGeodeticCurve(Ellipsoid ellipsoid,</p></blockquote>
<blockquote class="codeline4"><p>GlobalCoordinates start, GlobalCoordinates end)</p></blockquote>
<blockquote class="codeline2"><p>{</p></blockquote>
<blockquote class="codeline3"><p>// get constants</p></blockquote>
<blockquote class="codeline3"><p>double a = ellipsoid.SemiMajorAxis;</p></blockquote>
<blockquote class="codeline3"><p>double b = ellipsoid.SemiMinorAxis;</p></blockquote>
<blockquote class="codeline3"><p>double f = ellipsoid.Flattening;</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline3"><p>// get parameters as radians</p></blockquote>
<blockquote class="codeline3"><p>double phi1 = start.Latitude.Radians;</p></blockquote>
<blockquote class="codeline3"><p>double lambda1 = start.Longitude.Radians;</p></blockquote>
<blockquote class="codeline3"><p>double phi2 = end.Latitude.Radians;</p></blockquote>
<blockquote class="codeline3"><p>double lambda2 = end.Longitude.Radians;</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline3"><p>// calculations</p></blockquote>
<blockquote class="codeline3"><p>double a2 = a * a;</p></blockquote>
<blockquote class="codeline3"><p>double b2 = b * b;</p></blockquote>
<blockquote class="codeline3"><p>double a2b2b2 = (a2 &#8211; b2) / b2;</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline3"><p>double omega = lambda2 &#8211; lambda1;</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline3"><p>double tanphi1 = Math.Tan(phi1);</p></blockquote>
<blockquote class="codeline3"><p>double tanU1 = (1.0 &#8211; f) * tanphi1;</p></blockquote>
<blockquote class="codeline3"><p>double U1 = Math.Atan(tanU1);</p></blockquote>
<blockquote class="codeline3"><p>double sinU1 = Math.Sin(U1);</p></blockquote>
<blockquote class="codeline3"><p>double cosU1 = Math.Cos(U1);</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline3"><p>double tanphi2 = Math.Tan(phi2);</p></blockquote>
<blockquote class="codeline3"><p>double tanU2 = (1.0 &#8211; f) * tanphi2;</p></blockquote>
<blockquote class="codeline3"><p>double U2 = Math.Atan(tanU2);</p></blockquote>
<blockquote class="codeline3"><p>double sinU2 = Math.Sin(U2);</p></blockquote>
<blockquote class="codeline3"><p>double cosU2 = Math.Cos(U2);</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline3"><p>double sinU1sinU2 = sinU1 * sinU2;</p></blockquote>
<blockquote class="codeline3"><p>double cosU1sinU2 = cosU1 * sinU2;</p></blockquote>
<blockquote class="codeline3"><p>double sinU1cosU2 = sinU1 * cosU2;</p></blockquote>
<blockquote class="codeline3"><p>double cosU1cosU2 = cosU1 * cosU2;</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline3"><p>// eq. 13</p></blockquote>
<blockquote class="codeline3"><p>double lambda = omega;</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline3"><p>// intermediates we&#8217;ll need to compute &#8217;s&#8217;</p></blockquote>
<blockquote class="codeline3"><p>double A = 0.0;</p></blockquote>
<blockquote class="codeline3"><p>double B = 0.0;</p></blockquote>
<blockquote class="codeline3"><p>double sigma = 0.0;</p></blockquote>
<blockquote class="codeline3"><p>double deltasigma = 0.0;</p></blockquote>
<blockquote class="codeline3"><p>double lambda0;</p></blockquote>
<blockquote class="codeline3"><p>bool converged = false;</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline3"><p>for (int i = 0; i &lt; 10; i++)</p></blockquote>
<blockquote class="codeline3"><p>{</p></blockquote>
<blockquote class="codeline4"><p>lambda0 = lambda;</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline4"><p>double sinlambda = Math.Sin(lambda);</p></blockquote>
<blockquote class="codeline4"><p>double coslambda = Math.Cos(lambda);</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline4"><p>// eq. 14</p></blockquote>
<blockquote class="codeline4"><p>double sin2sigma = (cosU2 * sinlambda * cosU2 * sinlambda)</p></blockquote>
<blockquote class="codeline6"><p>+ (cosU1sinU2 &#8211; sinU1cosU2 * coslambda)</p></blockquote>
<blockquote class="codeline6"><p>* (cosU1sinU2 &#8211; sinU1cosU2 * coslambda);</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline4"><p>double sinsigma = Math.Sqrt(sin2sigma);</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline4"><p>// eq. 15</p></blockquote>
<blockquote class="codeline4"><p>double cossigma = sinU1sinU2 + (cosU1cosU2 * coslambda);</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline4"><p>// eq. 16</p></blockquote>
<blockquote class="codeline4"><p>sigma = Math.Atan2(sinsigma, cossigma);</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline4"><p>// eq. 17 Careful! sin2sigma might be almost 0!</p></blockquote>
<blockquote class="codeline4"><p>double sinalpha = (sin2sigma == 0) ? 0.0</p></blockquote>
<blockquote class="codeline6"><p>: cosU1cosU2 * sinlambda / sinsigma;</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline4"><p>double alpha = Math.Asin(sinalpha);</p></blockquote>
<blockquote class="codeline4"><p>double cosalpha = Math.Cos(alpha);</p></blockquote>
<blockquote class="codeline4"><p>double cos2alpha = cosalpha * cosalpha;</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline4"><p>// eq. 18 Careful! cos2alpha might be almost 0!</p></blockquote>
<blockquote class="codeline4"><p>double cos2sigmam = cos2alpha == 0.0 ? 0.0</p></blockquote>
<blockquote class="codeline6"><p>: cossigma &#8211; 2 * sinU1sinU2 / cos2alpha;</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline4"><p>double u2 = cos2alpha * a2b2b2;</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline4"><p>double cos2sigmam2 = cos2sigmam * cos2sigmam;</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline4"><p>// eq. 3</p></blockquote>
<blockquote class="codeline4"><p>A = 1.0 + u2 / 16384 * (4096 + u2 * (-768 + u2 * (320 &#8211; 175 * u2)));</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline4"><p>// eq. 4</p></blockquote>
<blockquote class="codeline4"><p>B = u2 / 1024 * (256 + u2 * (-128 + u2 * (74 &#8211; 47 * u2)));</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline4"><p>// eq. 6</p></blockquote>
<blockquote class="codeline4"><p>deltasigma = B * sinsigma * (cos2sigmam + B / 4</p></blockquote>
<blockquote class="codeline6"><p>* (cossigma * (-1 + 2 * cos2sigmam2) &#8211; B / 6 * cos2sigmam</p></blockquote>
<blockquote class="codeline6"><p>* (-3 + 4 * sin2sigma) * (-3 + 4 * cos2sigmam2)));</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline4"><p>// eq. 10</p></blockquote>
<blockquote class="codeline4"><p>double C = f / 16 * cos2alpha * (4 + f * (4 &#8211; 3 * cos2alpha));</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline4"><p>// eq. 11 (modified)</p></blockquote>
<blockquote class="codeline4"><p>lambda = omega + (1 &#8211; C) * f * sinalpha</p></blockquote>
<blockquote class="codeline6"><p>* (sigma + C * sinsigma * (cos2sigmam + C * cossigma * (-1 + 2 * cos2sigmam2)));</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline4"><p>// see how much improvement we got</p></blockquote>
<blockquote class="codeline4"><p>double change = Math.Abs((lambda &#8211; lambda0) / lambda);</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline4"><p>if ((i &gt; 1) &amp;&amp; (change &lt; 0.0000000000001))</p></blockquote>
<blockquote class="codeline4"><p>{</p></blockquote>
<blockquote class="codeline5"><p>converged = true;</p></blockquote>
<blockquote class="codeline5"><p>break;</p></blockquote>
<blockquote class="codeline4"><p>}</p></blockquote>
<blockquote class="codeline3"><p>}</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline3"><p>// eq. 19</p></blockquote>
<blockquote class="codeline3"><p>double s = b * A * (sigma &#8211; deltasigma);</p></blockquote>
<blockquote class="codeline3"><p>Angle alpha1;</p></blockquote>
<blockquote class="codeline3"><p>Angle alpha2;</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline3"><p>// didn&#8217;t converge? must be N/S</p></blockquote>
<blockquote class="codeline3"><p>if (!converged)</p></blockquote>
<blockquote class="codeline3"><p>{</p></blockquote>
<blockquote class="codeline4"><p>if (phi1 &gt; phi2)</p></blockquote>
<blockquote class="codeline4"><p>{</p></blockquote>
<blockquote class="codeline5"><p>alpha1 = Angle.Angle180;</p></blockquote>
<blockquote class="codeline5"><p>alpha2 = Angle.Zero;</p></blockquote>
<blockquote class="codeline4"><p>}</p></blockquote>
<blockquote class="codeline4"><p>else if (phi1 &lt; phi2)</p></blockquote>
<blockquote class="codeline4"><p>{</p></blockquote>
<blockquote class="codeline5"><p>alpha1 = Angle.Zero;</p></blockquote>
<blockquote class="codeline5"><p>alpha2 = Angle.Angle180;</p></blockquote>
<blockquote class="codeline4"><p>}</p></blockquote>
<blockquote class="codeline4"><p>else</p></blockquote>
<blockquote class="codeline4"><p>{</p></blockquote>
<blockquote class="codeline5"><p>alpha1 = new Angle(Double.NaN);</p></blockquote>
<blockquote class="codeline5"><p>alpha2 = new Angle(Double.NaN);</p></blockquote>
<blockquote class="codeline4"><p>}</p></blockquote>
<blockquote class="codeline3"><p>}</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline3"><p>// else, it converged, so do the math</p></blockquote>
<blockquote class="codeline3"><p>else</p></blockquote>
<blockquote class="codeline3"><p>{</p></blockquote>
<blockquote class="codeline4"><p>double radians;</p></blockquote>
<blockquote class="codeline4"><p>alpha1 = new Angle();</p></blockquote>
<blockquote class="codeline4"><p>alpha2 = new Angle();</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline4"><p>// eq. 20</p></blockquote>
<blockquote class="codeline4"><p>radians = Math.Atan2(cosU2 * Math.Sin(lambda),</p></blockquote>
<blockquote class="codeline6"><p>(cosU1sinU2 &#8211; sinU1cosU2 * Math.Cos(lambda)));</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline4"><p>if (radians &lt; 0.0) radians += TwoPi;</p></blockquote>
<blockquote class="codeline4"><p>alpha1.Radians = radians;</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline4"><p>// eq. 21</p></blockquote>
<blockquote class="codeline4"><p>radians = Math.Atan2(cosU1 * Math.Sin(lambda),</p></blockquote>
<blockquote class="codeline6"><p>(-sinU1cosU2 + cosU1sinU2 * Math.Cos(lambda))) + Math.PI;</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline4"><p>if (radians &lt; 0.0) radians += TwoPi;</p></blockquote>
<blockquote class="codeline4"><p>alpha2.Radians = radians;</p></blockquote>
<blockquote class="codeline3"><p>}</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline3"><p>return new GeodeticCurve(s, alpha1, alpha2);</p></blockquote>
<blockquote class="codeline2"><p>}</p></blockquote>
<blockquote class="codeline1"><p>}</p></blockquote>
<blockquote class="codeline0"><p>}</p></blockquote>
</blockquote>
<p>There you have it! You have the tools you need to know the answer to the question &#8220;How far is it from here to there?&#8221;</p>
<p>Here&#8217;s an example of using the code to calculate how far it is from the <a target="_blank" href="http://www.nps.gov/linc/" title="Lincoln Memorial">Lincoln Memorial</a> in Washington, D.C. to the <a target="_blank" href="http://www.tour-eiffel.fr/teiffel/uk/" title="Eiffle Tower">Eiffel Tower</a> in Paris:</p>
<blockquote class="codeblock">
<blockquote class="codeline0"><p>using System;</p></blockquote>
<blockquote class="codeline0"><p>using System.Text;</p></blockquote>
<blockquote class="codeline0"><p>using Gavaghan.Geodesy;</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline0"><p>namespace Gavaghan.Geodesy.Example</p></blockquote>
<blockquote class="codeline0"><p>{</p></blockquote>
<blockquote class="codeline1"><p>public class Example</p></blockquote>
<blockquote class="codeline1"><p>{</p></blockquote>
<blockquote class="codeline2"><p>static void Main()</p></blockquote>
<blockquote class="codeline2"><p>{</p></blockquote>
<blockquote class="codeline3"><p>// instantiate the calculator</p></blockquote>
<blockquote class="codeline3"><p>GeodeticCalculator geoCalc = new GeodeticCalculator();</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline3"><p>// select a reference elllipsoid</p></blockquote>
<blockquote class="codeline3"><p>Ellipsoid reference = Ellipsoid.WGS84;</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline3"><p>// set Lincoln Memorial coordinates</p></blockquote>
<blockquote class="codeline3"><p>GlobalCoordinates lincolnMemorial;</p></blockquote>
<blockquote class="codeline3"><p>lincolnMemorial = new GlobalCoordinates(</p></blockquote>
<blockquote class="codeline5"><p>new Angle(38.88922), new Angle(-77.04978)</p></blockquote>
<blockquote class="codeline3"><p>);</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline3"><p>// set Eiffel Tower coordinates</p></blockquote>
<blockquote class="codeline3"><p>GlobalCoordinates eiffelTower;</p></blockquote>
<blockquote class="codeline3"><p>eiffelTower = new GlobalCoordinates(</p></blockquote>
<blockquote class="codeline5"><p>new Angle(48.85889), new Angle(2.29583)</p></blockquote>
<blockquote class="codeline3"><p>);</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline3"><p>// calculate the geodetic curve</p></blockquote>
<blockquote class="codeline3"><p>GeodeticCurve geoCurve = geoCalc.CalculateGeodeticCurve(</p></blockquote>
<blockquote class="codeline5"><p>reference, lincolnMemorial, eiffelTower</p></blockquote>
<blockquote class="codeline3"><p>);</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline3"><p>double ellipseKilometers = geoCurve.EllipsoidalDistance / 1000.0;</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline3"><p>Console.WriteLine(&#8220;Lincoln Memorial to Eiffel Tower using WGS84&#8243;);</p></blockquote>
<blockquote class="codeline3"><p>Console.WriteLine(&#8221; Ellipsoidal Distance: {0:0.00} kilometers&#8221;,</p></blockquote>
<blockquote class="codeline5"><p>ellipseKilometers</p></blockquote>
<blockquote class="codeline3"><p>);</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline3"><p>Console.WriteLine(&#8221; Azimuth: {0:0.00} degrees&#8221;,</p></blockquote>
<blockquote class="codeline5"><p>geoCurve.Azimuth.Degrees</p></blockquote>
<blockquote class="codeline3"><p>);</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline3"><p>Console.WriteLine(&#8221; Reverse Azimuth: {0:0.00} degrees&#8221;,</p></blockquote>
<blockquote class="codeline5"><p>geoCurve.ReverseAzimuth.Degrees</p></blockquote>
<blockquote class="codeline3"><p>);</p></blockquote>
<blockquote class="codeline2"><p>}</p></blockquote>
<blockquote class="codeline1"><p>}</p></blockquote>
<blockquote class="codeline0"><p>}</p></blockquote>
</blockquote>
<p>The library also supports 3-D geodetic calculations (measurements that account for the elevation above or below the reference ellipsoid). For complete source code, documentation, and examples, <a href="http://www.gavaghan.org/blog/free-source-code/geodesy-library-vincentys-formula/" title="C# Geodesy Vincenty's Formula">download the entire C# library</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gavaghan.org/blog/2007/08/06/c-gps-receivers-and-geocaching-vincentys-formula/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
<enclosure url="http://www.gavaghan.org/blog/uploads/geocaching/Geocaching.mpg" length="8263872" type="video/mpeg" />
		</item>
		<item>
		<title>C# Grief With Overloaded Operators</title>
		<link>http://www.gavaghan.org/blog/2007/07/31/csharp-grief-with-overloaded-operators/</link>
		<comments>http://www.gavaghan.org/blog/2007/07/31/csharp-grief-with-overloaded-operators/#comments</comments>
		<pubDate>Tue, 31 Jul 2007 17:37:13 +0000</pubDate>
		<dc:creator>Mike Gavaghan</dc:creator>
				<category><![CDATA[CodeProject]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://www.gavaghan.org/blog/2007/07/31/csharp-grief-with-overloaded-operators/</guid>
		<description><![CDATA[Here's a nasty bug that crept into one of my team's projects recently. When will equivalent C# objects fail to compare as equal? The answer is "when operator== doesn't work as expected."]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s a nasty bug that crept into one of my team&#8217;s projects recently. When will equivalent C# objects fail to compare as equal? The answer is &#8220;when <code>operator==</code> doesn&#8217;t work as expected.&#8221;</p>
<p><span id="more-33"></span>Take a look at this method. It&#8217;s similar to a method I ran across that was intended to provide a generic means of performing some behavior based on the equivalence of two values:</p>
<blockquote class="codeblock">
<blockquote class="codeline0"><p>static public void DoSomeWork(object obj1, object obj2)</p></blockquote>
<blockquote class="codeline0"><p>{</p></blockquote>
<blockquote class="codeline1"><p>Console.WriteLine(&#8220;obj1 = &#8221; + obj1 + &#8220;; obj2 = &#8221; + obj2 + &#8220;;&#8221;);</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline1"><p>if (obj1 == obj2)</p></blockquote>
<blockquote class="codeline1"><p>{</p></blockquote>
<blockquote class="codeline2"><p>Console.WriteLine(&#8220;Objects are equal&#8221;);</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline2"><p>// do some important work</p></blockquote>
<blockquote class="codeline1"><p>}</p></blockquote>
<blockquote class="codeline1"><p>else</p></blockquote>
<blockquote class="codeline1"><p>{</p></blockquote>
<blockquote class="codeline3"><p>Console.WriteLine(&#8220;Objects are NOT equal&#8221;);</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline3"><p>// do some different important work</p></blockquote>
<blockquote class="codeline1"><p>}</p></blockquote>
<blockquote class="codeline0"><p>}</p></blockquote>
</blockquote>
<p>Note the use of <code>operator==</code> being applied to two parameters of type <code>object</code>. The idea here is we can pass objects of any type: <code>int</code>, <code>string</code>, or some complex type that implements <code>Equals()</code>. No matter what we pass, we want the code to branch based on the equivalence of the arguments.</p>
<p>Now, as a former Java developer, I never would have coded it this way. In Java, &#8220;<nobr><code>obj1 == obj2</code></nobr>&#8221; is <em>always</em> a reference comparison. It evaluates to true if, and only if, both arguments refer to precisely the same object instance. To compare objects for equivalence, Java programmers explictly test &#8220;<code>obj1.equals(obj2)</code>&#8220;.</p>
<p>In my C++ days, I learned that operator overloading is a risky endeavor that generally should be avoided. Given a flat class hierarchy, you&#8217;re probably safe. But, sometimes the operator functionality that gets invoked on a derived object cast as a base type is non-intuitive.</p>
<p>Like in this C# example.</p>
<p>Look what happens when we pass equivalent string instances to the above method.</p>
<blockquote class="codeblock">
<blockquote class="codeline0"><p>static void Main()</p></blockquote>
<blockquote class="codeline0"><p>{</p></blockquote>
<blockquote class="codeline1"><p>// build the first string</p></blockquote>
<blockquote class="codeline1"><p>string str1 = &#8220;foobar&#8221;;</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline1"><p>// make the second string equivalent</p></blockquote>
<blockquote class="codeline1"><p>// use concatenation to prevent compiler optimization</p></blockquote>
<blockquote class="codeline1"><p>string str2 = String.Concat(&#8220;foo&#8221;, &#8220;bar&#8221;);</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline1"><p>DoSomeWork(str1, str2);</p></blockquote>
<blockquote class="codeline1"><p>}</p></blockquote>
</blockquote>
<p>Note how the second string is built using concatenation. This is necessary to prevent the compiler from using the same instance of the string literal on both assignments (this would invalidate our test).</p>
<p>With our string instances both equivalent to &#8220;foobar&#8221;, we call our test method and get:</p>
<blockquote class="codeouttake"><p>obj1 = foobar; obj2 = foobar;<br />
Objects are NOT equal</p></blockquote>
<p>What&#8217;s up with that? <em>Every</em> C# developer knows that <code>"foobar" == "foobar"</code> will <em>always</em> evaluate to true since, unlike Java, C# is &#8220;smart&#8221; enough to invoke the <code>Equals()</code> method when <code>operator==</code> is called on two strings.</p>
<p>The problem lies in the fact that <code>operator==</code> is a <strong>static</strong> method that must be resolved at <strong>compile time</strong>, not a polymorphing method selected at runtime.</p>
<p>If <code>obj1</code> and <code>obj2</code> were explicity cast as <code>string</code>, the code would work as expected. The static method <code>operator==( <strong>string</strong> str1, <strong>string</strong> str2 )</code> method is implemented to invoke <code>Equals()</code> for you. The <code>Equals()</code> method on type <code>object</code> is declared <code>virtual</code>, so it is a polymorphic method.</p>
<p>However, in our <code>DoSomeWork()</code> example, the parameters are cast as <code>object</code>. So, the static <code>operator==( <strong>object</strong> obj1, <strong>object</strong> obj2 )</code> method is selected at compile time. And that implementation of the overloaded <code>==</code> operator only performs an object reference comparison. The <code>Equals()</code> method is never invoked!</p>
<p>A similar problem occurs if you try to pass a value type. The value types will get boxed before <code>DoSomeWork()</code> gets called. Hence, even &#8220;<code>2 == 2</code>&#8221; will evaluate to false.</p>
<p>The solution? Rewrite <code>DoSomeWork()</code> to invoke <code>Equals()</code>:</p>
<blockquote class="codeblock">
<blockquote class="codeline0"><p>static public void DoSomeWork(object obj1, object obj2)</p></blockquote>
<blockquote class="codeline0"><p>{</p></blockquote>
<blockquote class="codeline1"><p>Console.WriteLine(&#8220;obj1 = &#8221; + obj1 + &#8220;; obj2 = &#8221; + obj2 + &#8220;;&#8221;);</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline1"><p>if (obj1.Equals(obj2))</p></blockquote>
<blockquote class="codeline1"><p>{</p></blockquote>
<blockquote class="codeline2"><p>Console.WriteLine(&#8220;Objects are equal&#8221;);</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline2"><p>// do some important work</p></blockquote>
<blockquote class="codeline1"><p>}</p></blockquote>
<blockquote class="codeline1"><p>else</p></blockquote>
<blockquote class="codeline1"><p>{</p></blockquote>
<blockquote class="codeline2"><p>Console.WriteLine(&#8220;Objects are NOT equal&#8221;);</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline2"><p>// do some different important work</p></blockquote>
<blockquote class="codeline1"><p>}</p></blockquote>
<blockquote class="codeline0"><p>}</p></blockquote>
</blockquote>
<p>Now, we&#8217;ll get the comparison behavior we wanted.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gavaghan.org/blog/2007/07/31/csharp-grief-with-overloaded-operators/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Intercepting Add and Remove of C# Event Delegates</title>
		<link>http://www.gavaghan.org/blog/2007/07/25/intercepting-add-and-remove-of-c-event-delegates/</link>
		<comments>http://www.gavaghan.org/blog/2007/07/25/intercepting-add-and-remove-of-c-event-delegates/#comments</comments>
		<pubDate>Wed, 25 Jul 2007 12:15:46 +0000</pubDate>
		<dc:creator>Mike Gavaghan</dc:creator>
				<category><![CDATA[CodeProject]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://www.gavaghan.org/blog/2007/07/25/intercepting-add-and-remove-of-c-event-delegates/</guid>
		<description><![CDATA[All you geniuses and rocket scientists out there probably already know this, but I just stumbled on it, and I think it's kind of cool. Did you know you can customize the adding and removing of C# event handlers? I didn't.

I'm going to end this post with the question "Yes, but what's it good for?" You folks with the Ph. D. in C#, feel free to scroll to the bottom and post your answers. For my fellow mortals out there, let me recap what I'm talking about.]]></description>
			<content:encoded><![CDATA[<p>All you geniuses and rocket scientists out there probably already know this, but I just stumbled on it, and I think it&#8217;s kind of cool. Did you know you can customize the adding and removing of C# event handlers? I didn&#8217;t.</p>
<p>I&#8217;m going to end this post with the question &#8220;Yes, but what&#8217;s it <em>good</em> for?&#8221; You folks with the Ph. D. in C#, feel free to scroll to the bottom and post your answers. For my fellow mortals out there, let me recap what I&#8217;m talking about.</p>
<p><span id="more-16"></span>We all know how to declare events on a class, right? It goes something like this:</p>
<blockquote class="codeblock">
<blockquote class="codeline0"><p>using System;</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline0"><p>namespace AddRemoveDelegates</p></blockquote>
<blockquote class="codeline0"><p>{</p></blockquote>
<blockquote class="codeline1"><p>public class Account</p></blockquote>
<blockquote class="codeline1"><p>{</p></blockquote>
<blockquote class="codeline2"><p>private decimal balance;</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline2"><p>public event EventHandler&lt;EventArgs&gt; Overdrawn;</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline2"><p>public decimal Balance</p></blockquote>
<blockquote class="codeline2"><p>{</p></blockquote>
<blockquote class="codeline3"><p>get { return balance; }</p></blockquote>
<blockquote class="codeline3"><p>set { balance = value;}</p></blockquote>
<blockquote class="codeline2"><p>}</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline2"><p>public void UpdateBalance(decimal amount)</p></blockquote>
<blockquote class="codeline2"><p>{</p></blockquote>
<blockquote class="codeline3"><p>balance += amount;</p></blockquote>
<blockquote class="codeline3"><p>if (balance &lt; 0)</p></blockquote>
<blockquote class="codeline3"><p>{</p></blockquote>
<blockquote class="codeline4"><p>if (Overdrawn != null) Overdrawn(this, EventArgs.Empty);</p></blockquote>
<blockquote class="codeline3"><p>}</p></blockquote>
<blockquote class="codeline2"><p>}</p></blockquote>
<blockquote class="codeline1"><p>}</p></blockquote>
<blockquote class="codeline0"><p>}</p></blockquote>
</blockquote>
<p>Straightforward, right? If the account balance goes below zero, we fire the <code>Overdrawn</code> event. We hook up listeners to the event like this:</p>
<blockquote class="codeblock">
<blockquote class="codeline0"><p>using System;</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline0"><p>namespace AddRemoveDelegates</p></blockquote>
<blockquote class="codeline0"><p>{</p></blockquote>
<blockquote class="codeline1"><p>class Example</p></blockquote>
<blockquote class="codeline1"><p>{</p></blockquote>
<blockquote class="codeline2"><p>public static void account_Overdrawn( object sender, EventArgs e )</p></blockquote>
<blockquote class="codeline2"><p>{</p></blockquote>
<blockquote class="codeline3"><p>Console.WriteLine(&#8220;Account is overdrawn&#8221;);</p></blockquote>
<blockquote class="codeline2"><p>}</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline2"><p>public static void Main(string[] args)</p></blockquote>
<blockquote class="codeline2"><p>{</p></blockquote>
<blockquote class="codeline3"><p>Account account = new Account();</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline3"><p>// hookup the event listener</p></blockquote>
<blockquote class="codeline3"><p>account.Overdrawn += account_Overdrawn;</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline3"><p>account.UpdateBalance(-10);</p></blockquote>
<blockquote class="codeline2"><p>}</p></blockquote>
<blockquote class="codeline1"><p>}</p></blockquote>
<blockquote class="codeline0"><p>}</p></blockquote>
</blockquote>
<p>For the most part, it&#8217;s as easy as that. But, have you ever wondered just what magic is going on inside that call to <code>+=</code> ?</p>
<p>Take a moment to consider the <code>Balance</code> property on the <code>Account</code> class we defined above. How do we access it? Well, first we have to back it up with a private field (named <code>balance</code> with a lowercase &#8220;b&#8221;). Then, we define <code>get</code> and <code>set</code> implementations to control how the private field is accessed and altered. They teach that in Day 1 of a C# programming class.</p>
<p><code>event</code> members work largely the same way, except the compiler does some work behind the scenes on your behalf. When you declare an event, the compiler gives you a hidden <code>MulticastDelegate</code> field that manages a collection of event listeners. The <code>+=</code> and <code>-=</code> operators are implemented to add and remove the handlers from the hidden delegate.</p>
<p>However, you have the ability to explicitly implement your own behavior for <code>+=</code> and <code>-=</code> using the keywords <code>add</code> and <code>remove</code>, respectively, just as properties use <code>get</code> and <code>set</code>.</p>
<p>Here&#8217;s an alternate implementation of the <code>Account</code> class:</p>
<blockquote class="codeblock">
<blockquote class="codeline0"><p>using System;</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline0"><p>namespace AddRemoveDelegates</p></blockquote>
<blockquote class="codeline0"><p>{</p></blockquote>
<blockquote class="codeline1"><p>public class Account</p></blockquote>
<blockquote class="codeline1"><p>{</p></blockquote>
<blockquote class="codeline2"><p>private decimal balance;</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline2"><p>// we have to explicitly declare a MulticastDelegate</p></blockquote>
<blockquote class="codeline2"><p>private EventHandler&lt;EventArgs&gt; onOverdrawn;</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline2"><p>// here, we control the adding and removing of listeners</p></blockquote>
<blockquote class="codeline2"><p>public event EventHandler&lt;EventArgs&gt; Overdrawn</p></blockquote>
<blockquote class="codeline2"><p>{</p></blockquote>
<blockquote class="codeline3"><p>add</p></blockquote>
<blockquote class="codeline3"><p>{</p></blockquote>
<blockquote class="codeline4"><p>onOverdrawn =</p></blockquote>
<blockquote class="codeline6"><p>(EventHandler&lt;EventArgs&gt;)Delegate.Combine(onOverdrawn, value);</p></blockquote>
<blockquote class="codeline3"><p>}</p></blockquote>
<blockquote class="codeline3"><p>remove</p></blockquote>
<blockquote class="codeline3"><p>{</p></blockquote>
<blockquote class="codeline4"><p>onOverdrawn =</p></blockquote>
<blockquote class="codeline6"><p>(EventHandler&lt;EventArgs&gt;)Delegate.Remove(onOverdrawn, value);</p></blockquote>
<blockquote class="codeline3"><p>}</p></blockquote>
<blockquote class="codeline2"><p>}</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline2"><p>public decimal Balance</p></blockquote>
<blockquote class="codeline2"><p>{</p></blockquote>
<blockquote class="codeline3"><p>get { return balance; }</p></blockquote>
<blockquote class="codeline3"><p>set { balance = value;}</p></blockquote>
<blockquote class="codeline2"><p>}</p></blockquote>
<blockquote class="blankcodeline"></blockquote>
<blockquote class="codeline2"><p>public void UpdateBalance(decimal amount)</p></blockquote>
<blockquote class="codeline2"><p>{</p></blockquote>
<blockquote class="codeline3"><p>balance += amount;</p></blockquote>
<blockquote class="codeline3"><p>if (balance &lt; 0)</p></blockquote>
<blockquote class="codeline3"><p>{</p></blockquote>
<blockquote class="codeline4"><p>// we also have to invoke the delegate through the field, now</p></blockquote>
<blockquote class="codeline4"><p>if (onOverdrawn != null) onOverdrawn(this, EventArgs.Empty);</p></blockquote>
<blockquote class="codeline3"><p>}</p></blockquote>
<blockquote class="codeline2"><p>}</p></blockquote>
<blockquote class="codeline1"><p>}</p></blockquote>
<blockquote class="codeline0"><p>}</p></blockquote>
</blockquote>
<p>We&#8217;ve added a private field of type <code>EventHandler&lt;EventArgs&gt;</code> called <code>onOverdrawn</code>. <code>EventHandler&lt;EventsArgs&gt;</code> is a subtype of <code>System.MulticastDelegate</code>, and this will be our collection of registered event listeners. We&#8217;ve also created <code>add</code> and <code>remove</code> implementations for the <code>Overdrawn</code> event. Using static methods <code>Combine</code> and <code>Remove</code> on the <code>Delegate</code> class, we can update the listeners in our <code>MulticastDelegate</code>.</p>
<p>We haven&#8217;t gained anything, yet. This is what C# would otherwise give us for free. But, think about the possibilities! Yes! The possibilities!</p>
<p>What possibilities?</p>
<p><strong>Yes, but what&#8217;s it <em>good</em> for?</strong></p>
<p>When the only tool you have is a hammer, every problem looks like a nail &#8212; and this is a <em>really</em> cool hammer. It&#8217;s got what I call &#8220;geek appeal&#8221;. It&#8217;s a clever trick to show other developers so they can bow at your genius. Unfortunately, I&#8217;m kind of at a loss for a legitimate use &#8212; except maybe for some contrived examples.</p>
<p>I don&#8217;t like creating side effects in what is traditionally a simple and well understood concept &#8212; the <a target="_blank" href="http://en.wikipedia.org/wiki/Observer_pattern" title="Observer Pattern">Observer Pattern</a>. Making code do something unexpected is likely to confound clients of your class unless the behavior is very narrow and contained in scope. Why solve a problem by injecting specialized behavior into event management when you can solve it somewhere else?</p>
<p>Okay, logging the adding and removing of listeners might make sense. Perhaps even supporting thread synchronization would make sense (you might want to prevent changes in the <code>MulticastDelegate</code> while an event is in the middle of firing).</p>
<p>Still, it seems like something a junior programmer would do just to show off &#8211; but unwittingly invite trouble at the same time.</p>
<p>What do <em>you</em> think? Have you used this before? Can you envision any problems where custom event listener management is the ideal solution?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gavaghan.org/blog/2007/07/25/intercepting-add-and-remove-of-c-event-delegates/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
	</channel>
</rss>

