<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" version="2.0">
  <channel>
    <title>Clemens Vasters - Technology|CLR</title>
    <link>http://vasters.com/clemensv/</link>
    <description>Cloud Development and Alien Abductions</description>
    <language>en-us</language>
    <copyright>Clemens Vasters</copyright>
    <lastBuildDate>Thu, 06 Sep 2012 19:08:10 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 1.9.7067.0</generator>
    <managingEditor>cvasters@guhhome.com</managingEditor>
    <webMaster>cvasters@guhhome.com</webMaster>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=8a8c025a-365e-4f15-9f89-07a0233ba669</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,8a8c025a-365e-4f15-9f89-07a0233ba669.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,8a8c025a-365e-4f15-9f89-07a0233ba669.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=8a8c025a-365e-4f15-9f89-07a0233ba669</wfw:commentRss>
      <slash:comments>14</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
as I thumb through some people's code on Github, I see a fairly large number of "catch
all" exception handling cases. It's difficult to blame folks for that, since there's
generally (and sadly) very little discipline about exception contracts and exception
masking, i.e. wrapping exceptions to avoid bubbling through failure conditions of
underlying implementation details. 
</p>
        <p>
If you're calling a function and that sits on a mountain of dependencies and folks
don't care about masking exceptions, there are many dozens of candidate exceptions
that can bubble back up to you and there's little chance to deal with them all or
even knowing them. Java has been trying to enforce more discipline in that regards,
but people cheat there with "catch all" as well.  There's also a question what
the right way tot deal with most exceptions is. In many cases, folks implement "intercept,
shrug and log" and mask the failure by telling users that something went wrong. In
other common cases, folks implement retries. It's actually fairly rare to see deeply
customized and careful reactions to particular exceptions. Again - things are complicated
and exceptions are supposed to be exceptional (reminder: throwing exceptions as part
of the regular happy path is horrifingly bad for performance and terrible from a style
perspective), so these blanket strategies are typically an efficient way of dealing
with things. 
</p>
        <p>
That all said ...
</p>
        <p>
          <strong>
            <em>Never, never ever</em>
          </strong> do this:
</p>
        <blockquote style="MARGIN-RIGHT: 0px" dir="ltr">
          <pre class="csharpcode">
            <span class="kwrd">try</span> {
Work(); } <span class="kwrd">catch</span> { }</pre>
        </blockquote>
        <p>
And  <strong><em>not even</em></strong> this:
</p>
        <blockquote style="MARGIN-RIGHT: 0px" dir="ltr">
          <pre class="csharpcode">
            <span class="kwrd">try</span> {
Work(); } <span class="kwrd">catch</span>(Exception e) { Trace.TraceError(e.ToString());
}</pre>
        </blockquote>
        <p>
Those examples are universally bad. (Yes, you will probably find examples of that
type even in the archive of this blog and some of my public code. Just goes to show
that I've learned some better coding practices here at Microsoft in the past 6 1/2
years.)
</p>
        <p>
The problem with them is that they catch not only the benign stuff, but they also
catch and suppress the C# runtime equivalent of the Zombie Apocalypse. If you get
thread-abort, out-of-memory, or stack-overflow exceptions thrown back at you, you
don't want to suppress those. Once you run into these, your code has ignored all the
red flags and exhausted its resources and whatever it was that you called didn't get
its job done and likely sits there as a zombie in an undefined state. That class of
exceptions is raining down your call stack like a shower of knife blades. They can't
happen. Your code must be defensively enough written to never run into that situation
and overtax resources in that way; if it does without you knowing what the root cause
is, this is an automatic "Priority 0", "drop-everything-you're-working-on" class bug.
It certainly is if you're writing services that need to stay up 99.95%+.
</p>
        <p>
What do we do? if we see any of those exceptions, it's an automatic death penalty
for the process. Once you see an unsafe out-of-memory exception or stack overflow,
you can't trust the state of the respective part of the system and likely not the
stability of the system. Mind that there's also a "it depends" here;  I would
follow a different strategy if I was talking about software for an autonomous Mars
Rover that can't crash even if its gravely ill.  There I would likely spend a
few months on the exception design and "what could go wrong here" before even thinking
about functionality, so that's a different ballgame.  In a cloud system, booting
a cluster machine that has the memory flu is a good strategy.
</p>
        <p>
Here's a variation of the helper we use:
</p>
        <blockquote style="MARGIN-RIGHT: 0px" dir="ltr">
          <pre class="csharpcode">
            <span class="kwrd">public</span>
            <span class="kwrd">static</span>
            <span class="kwrd">bool</span> IsFatal(<span class="kwrd">this</span> Exception
exception) { <span class="kwrd">while</span> (exception != <span class="kwrd">null</span>)
{ <span class="kwrd">if</span> (exception <span class="kwrd">as</span> OutOfMemoryException
!= <span class="kwrd">null</span> &amp;&amp; exception <span class="kwrd">as</span> InsufficientMemoryException
== <span class="kwrd">null</span> || exception <span class="kwrd">as</span> ThreadAbortException
!= <span class="kwrd">null</span> || 
<br />
exception <span class="kwrd">as</span> AccessViolationException != <span class="kwrd">null</span> ||
exception <span class="kwrd">as</span> SEHException != <span class="kwrd">null</span> ||
exception <span class="kwrd">as</span> StackOverflowException != <span class="kwrd">null</span>)
{ <span class="kwrd">return</span><span class="kwrd">true</span>; } <span class="kwrd">else</span> { <span class="kwrd">if</span> (exception <span class="kwrd">as</span> TypeInitializationException
== <span class="kwrd">null</span> &amp;&amp; exception <span class="kwrd">as</span> TargetInvocationException
== <span class="kwrd">null</span>) { <span class="kwrd">break</span>; } exception
= exception.InnerException; } } <span class="kwrd">return</span><span class="kwrd">false</span>;
}</pre>
        </blockquote>
        <style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
If you put this into a static utility class, you can use this on any exception as
an extension. And whenever you want to do a "catch all", you do this:
</p>
        <blockquote style="MARGIN-RIGHT: 0px" dir="ltr">
          <pre class="csharpcode">
            <span class="kwrd">try</span> {
DoWork();<br />
} <span class="kwrd">catch</span> (Exception e) { <span class="kwrd">if</span> (e.IsFatal())
{ <span class="kwrd">throw</span>; } Trace.TraceError(..., e); }</pre>
        </blockquote>
        <p>
If the exception is fatal, you simply throw it up as high as you can. Eventually it'll
end up on the bottom of whatever thread they happen on (where you might log and rethrow)
and will hopefully take the process with it. Threads marked as background threads
don't do that, so it's actually not a good idea to use those. These exceptions are
unhandled, process-terminating disasters with a resulting process crash-dump you want
to force in a 24/7 system so that you can weed them out one by one.
</p>
        <p>
(Update) As <a href="https://twitter.com/richardblewett/status/243792951229157378">Richard
Blewett pointed</a> out after reading this post, the StackOverflowException can't
be caught in .NET 2.0+, at all, and the ThreadAbortException automatically rethrows
even if you try to suppress it. There are two reasons for them to be on the list:
first, to shut up any code review debates about which of the .NET stock exceptions
are fatal and ought to be there; second, because code might (ab-)use these exceptions
as fail-fast exceptions and fake-throw them, or the exceptions might be blindly rethrown
when marshaled from a terminated background thread where they were caught at the bottom
of the thread. However they show up, it's always bad for them to show up.
</p>
        <p>
If you catch a falling knife, rethrow. <style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style></p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=8a8c025a-365e-4f15-9f89-07a0233ba669" />
      </body>
      <title>Are you catching falling knives?</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,8a8c025a-365e-4f15-9f89-07a0233ba669.aspx</guid>
      <link>http://vasters.com/clemensv/2012/09/06/Are+You+Catching+Falling+Knives.aspx</link>
      <pubDate>Thu, 06 Sep 2012 19:08:10 GMT</pubDate>
      <description>&lt;p&gt;
as I thumb through some people's code on Github, I see a fairly large number of "catch
all" exception handling cases. It's difficult to blame folks for that, since there's
generally (and sadly) very little discipline about exception contracts and exception
masking, i.e. wrapping exceptions to avoid bubbling through failure conditions of
underlying implementation details. 
&lt;/p&gt;
&lt;p&gt;
If you're calling a function and that sits on a mountain of dependencies and folks
don't care about masking exceptions, there are many dozens of candidate exceptions
that can bubble back up to you and there's little chance to deal with them all or
even knowing them. Java has been trying to enforce more discipline in that regards,
but people cheat there with "catch all" as well.&amp;nbsp; There's also a question what
the right way tot deal with most exceptions is. In many cases, folks implement "intercept,
shrug and log" and mask the failure by telling users that something went wrong. In
other common cases, folks implement retries. It's actually fairly rare to see deeply
customized and careful reactions to particular exceptions. Again - things are complicated
and exceptions are supposed to be exceptional (reminder: throwing exceptions as part
of the regular happy path is horrifingly bad for performance and terrible from a style
perspective), so these blanket strategies are typically an efficient way of dealing
with things. 
&lt;/p&gt;
&lt;p&gt;
That all said ...
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;&lt;em&gt;Never, never ever&lt;/em&gt;&lt;/strong&gt; do this:
&lt;/p&gt;
&lt;blockquote style="MARGIN-RIGHT: 0px" dir=ltr&gt;&lt;pre class=csharpcode&gt;&lt;span class=kwrd&gt;try&lt;/span&gt; {
Work(); } &lt;span class=kwrd&gt;catch&lt;/span&gt; { }&lt;/pre&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
And&amp;nbsp; &lt;strong&gt;&lt;em&gt;not even&lt;/em&gt;&lt;/strong&gt; this:
&lt;/p&gt;
&lt;blockquote style="MARGIN-RIGHT: 0px" dir=ltr&gt;&lt;pre class=csharpcode&gt;&lt;span class=kwrd&gt;try&lt;/span&gt; {
Work(); } &lt;span class=kwrd&gt;catch&lt;/span&gt;(Exception e) { Trace.TraceError(e.ToString());
}&lt;/pre&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Those examples are universally bad. (Yes, you will probably find examples of that
type even in the archive of this blog and some of my public code. Just goes to show
that I've learned some better coding practices here at Microsoft in the past 6 1/2
years.)
&lt;/p&gt;
&lt;p&gt;
The problem with them is that they catch not only the benign stuff, but they also
catch and suppress the C# runtime equivalent of the Zombie Apocalypse. If you get
thread-abort, out-of-memory, or stack-overflow exceptions thrown back at you, you
don't want to suppress those. Once you run into these, your code has ignored all the
red flags and exhausted its resources and whatever it was that you called didn't get
its job done and likely sits there as a zombie in an undefined state. That class of
exceptions is raining down your call stack like a shower of knife blades. They can't
happen. Your code must be defensively enough written to never run into that situation
and overtax resources in that way; if it does without you knowing what the root cause
is, this is an automatic "Priority 0", "drop-everything-you're-working-on" class bug.
It certainly is if you're writing services that need to stay up 99.95%+.
&lt;/p&gt;
&lt;p&gt;
What do we do? if we see any of those exceptions, it's an automatic death penalty
for the process. Once you see an unsafe out-of-memory exception or stack overflow,
you can't trust the state of the respective part of the system and likely not the
stability of the system. Mind that there's also a "it depends" here;&amp;nbsp; I would
follow a different strategy if I was talking about software for an autonomous Mars
Rover that can't crash even if its gravely ill.&amp;nbsp; There I would likely spend a
few months on the exception design and "what could go wrong here" before even thinking
about functionality, so that's a different ballgame.&amp;nbsp; In a cloud system, booting
a cluster machine that has the memory flu is a good strategy.
&lt;/p&gt;
&lt;p&gt;
Here's a variation of the helper we use:
&lt;/p&gt;
&lt;blockquote style="MARGIN-RIGHT: 0px" dir=ltr&gt;&lt;pre class=csharpcode&gt;&lt;span class=kwrd&gt;public&lt;/span&gt; &lt;span class=kwrd&gt;static&lt;/span&gt; &lt;span class=kwrd&gt;bool&lt;/span&gt; IsFatal(&lt;span class=kwrd&gt;this&lt;/span&gt; Exception
exception) { &lt;span class=kwrd&gt;while&lt;/span&gt; (exception != &lt;span class=kwrd&gt;null&lt;/span&gt;)
{ &lt;span class=kwrd&gt;if&lt;/span&gt; (exception &lt;span class=kwrd&gt;as&lt;/span&gt; OutOfMemoryException
!= &lt;span class=kwrd&gt;null&lt;/span&gt; &amp;amp;&amp;amp; exception &lt;span class=kwrd&gt;as&lt;/span&gt; InsufficientMemoryException
== &lt;span class=kwrd&gt;null&lt;/span&gt; || exception &lt;span class=kwrd&gt;as&lt;/span&gt; ThreadAbortException
!= &lt;span class=kwrd&gt;null&lt;/span&gt; || 
&lt;br&gt;
exception &lt;span class=kwrd&gt;as&lt;/span&gt; AccessViolationException != &lt;span class=kwrd&gt;null&lt;/span&gt; ||
exception &lt;span class=kwrd&gt;as&lt;/span&gt; SEHException != &lt;span class=kwrd&gt;null&lt;/span&gt; ||
exception &lt;span class=kwrd&gt;as&lt;/span&gt; StackOverflowException != &lt;span class=kwrd&gt;null&lt;/span&gt;)
{ &lt;span class=kwrd&gt;return&lt;/span&gt; &lt;span class=kwrd&gt;true&lt;/span&gt;; } &lt;span class=kwrd&gt;else&lt;/span&gt; { &lt;span class=kwrd&gt;if&lt;/span&gt; (exception &lt;span class=kwrd&gt;as&lt;/span&gt; TypeInitializationException
== &lt;span class=kwrd&gt;null&lt;/span&gt; &amp;amp;&amp;amp; exception &lt;span class=kwrd&gt;as&lt;/span&gt; TargetInvocationException
== &lt;span class=kwrd&gt;null&lt;/span&gt;) { &lt;span class=kwrd&gt;break&lt;/span&gt;; } exception = exception.InnerException;
} } &lt;span class=kwrd&gt;return&lt;/span&gt; &lt;span class=kwrd&gt;false&lt;/span&gt;; }&lt;/pre&gt;
&lt;/blockquote&gt; &lt;style type=text/css&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;p&gt;
If you put this into a static utility class, you can use this on any exception as
an extension. And whenever you want to do a "catch all", you do this:
&lt;/p&gt;
&lt;blockquote style="MARGIN-RIGHT: 0px" dir=ltr&gt;&lt;pre class=csharpcode&gt;&lt;span class=kwrd&gt;try&lt;/span&gt; {
DoWork();&lt;br&gt;
} &lt;span class=kwrd&gt;catch&lt;/span&gt; (Exception e) { &lt;span class=kwrd&gt;if&lt;/span&gt; (e.IsFatal())
{ &lt;span class=kwrd&gt;throw&lt;/span&gt;; } Trace.TraceError(..., e); }&lt;/pre&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
If the exception is fatal, you simply throw it up as high as you can. Eventually it'll
end up on the bottom of whatever thread they happen on (where you might log and rethrow)
and will hopefully take the process with it. Threads marked as background threads
don't do that, so it's actually not a good idea to use those. These exceptions are
unhandled, process-terminating disasters with a resulting process crash-dump you want
to force in a 24/7 system so that you can weed them out one by one.
&lt;/p&gt;
&lt;p&gt;
(Update) As &lt;a href="https://twitter.com/richardblewett/status/243792951229157378"&gt;Richard
Blewett pointed&lt;/a&gt; out after reading this post, the StackOverflowException can't
be caught in .NET 2.0+, at all,&amp;nbsp;and the ThreadAbortException automatically rethrows
even if you try to suppress it. There are two reasons for them to be on the list:
first, to shut up any code review debates about which of the .NET stock exceptions
are fatal and ought to be there; second, because code might (ab-)use these exceptions
as fail-fast exceptions and fake-throw them, or the exceptions might be blindly rethrown
when marshaled from a terminated background thread where they were caught at the bottom
of the thread. However they show up, it's always bad for them to show up.
&lt;/p&gt;
&lt;p&gt;
If you catch a falling knife, rethrow. &lt;style type=text/css&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=8a8c025a-365e-4f15-9f89-07a0233ba669" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,8a8c025a-365e-4f15-9f89-07a0233ba669.aspx</comments>
      <category>Technology</category>
      <category>Technology/CLR</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=3d2486d4-2bfa-446c-886b-bf336f92c861</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,3d2486d4-2bfa-446c-886b-bf336f92c861.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,3d2486d4-2bfa-446c-886b-bf336f92c861.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=3d2486d4-2bfa-446c-886b-bf336f92c861</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <blockquote>
          <p>
            <em>This post explains an essential class for asynchronous programming that lurks
in the depths of the WCF samples: InputQueue&lt;T&gt;. If you need to write efficient
server-side apps, you should consider reading through this and add InputQueue&lt;T&gt;
to your arsenal.  </em>
          </p>
        </blockquote>
        <p>
Let me start with: This blog post is 4 years late. Sorry! – and with that out of the
way:
</p>
        <p>
The <a href="http://msdn.microsoft.com/wcf">WCF</a> samples ship with several copies
of a class that’s marked as internal in the <em>System.ServiceModel.dll</em> assembly: <em>InputQueue&lt;T&gt;</em>.
Why are these samples – mostly those implementing channel-model extensions – bringing
local copies of this class with them? It’s an essential tool for implementing the
asynchronous call paths of many aspects of channels correctly and efficiently. 
</p>
        <p>
If you look closely enough, the WCF channel infrastructure resembles the Berkeley
Socket model quite a bit – especially on the server side. There’s a channel listener
that’s constructed on the server side and when that is <a href="http://msdn.microsoft.com/en-us/library/ms195524.aspx">opened</a> (usually
under the covers of the WCF ServiceHost) that operation is largely equivalent to calling
‘listen’ on a socket – the network endpoint is ready for business.  On sockets
you’ll then call ‘accept’ to accept the next available socket connection from a client,
in WCF you call ‘<a href="http://msdn.microsoft.com/en-us/library/ms195572.aspx">AcceptChannel</a>’
to accept the next available (session-) channel. On sockets you then call ‘receive’
to obtain bytes, on a channel you call ’<a href="http://msdn.microsoft.com/en-us/library/ms195339.aspx">Receive</a>’
to  obtain a message. 
</p>
        <p>
Before and between calls to '’AcceptChannel’ made by the server-side logic, 
client-initiated connections – and thus channels – may be coming in and queue up for
a bit before they handed out to the next caller of ‘AcceptChannel’, or the asynchronous
equivalent ‘Begin/EndAcceptChannel’ method pair. The number of channels that may be
pending is configured in WCF with the ‘<a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.nettcpbinding.listenbacklog.aspx">ListenBacklog</a>’
property that’s available on most bindings. 
</p>
        <p>
I wrote ‘queue up’ there since that’s precisely what happens – those newly created
channels on top of freshly accepted sockets or HTTP request channels are enqueued
into an <em>InputQueue&lt;T&gt;</em> instance and (Begin-)Accept is implemented as
a dequeue operation on that queue. There are two particular challenges here that make
the regular <em><a href="http://msdn.microsoft.com/en-us/library/7977ey2c.aspx">Queue&lt;T&gt;</a></em> class
from the <em>System.Collections.Generic</em> namespace unsuitable for use in the implementation
of that mechanism: Firstly, the <a href="http://msdn.microsoft.com/en-us/library/1c8bzx97.aspx"><em>Dequeue</em></a> method
there is only available as a synchronous variant and also doesn’t allow for specifying
a timeout. Secondly, the queue implementation doesn’t really help much with implementing
the <em>ListenBacklog</em> quota where not only the length of the queue is limited
to some configured number of entries, but accepting further connections/channels from
the underlying network is also suspended for as long as the queue is at capacity and
needs to resume as soon as the pressure is relieved, i.e. a caller takes a channel
out of the queue. 
</p>
        <p>
To show that <em>InputQueue&lt;T&gt;</em> is a very useful general purpose class even
outside of the context of the WCF channel infrastructure, I’ve lifted a version of
it from one of the most recent WCF channel samples, made a small number of modifications
that I’ll write about later, and created a little sample around it that I’ve attached
to this post. 
</p>
        <p>
The sample I’ll discuss here is simulating parsing/reading IP addresses from a log-file
and then performing a reverse DNS name resolution on those addresses – something that
you’d do in a web-server log-analyzer or as the background task in a blog engine wile
preparing statistics. 
</p>
        <p>
Reverse DNS name resolution is quite interesting since it’s embarrassingly easy to
parallelize and each resolution commonly takes a really long time (4-5 seconds) –whereby
all the work is done elsewhere. The process issuing the queries is mostly sitting
around idle waiting for the response.  Therefore, it’s a good idea to run a number
of DNS requests in parallel, but it’s a terrible idea to have any of these requests
execute as a blocking call and burning a thread. Since we’re assuming that we’re reading
from a log file that requires some parsing, it would also be a spectacularly bad idea
to have multiple concurrent threads compete for access to that file and get into each
other’s way. And since it is a file and we need to lift things up from disk, we probably
shouldn’t do that ‘just in time’ as a DNS resolution step is done, but there should
rather be some data readily waiting for processing.  <em>InputQueue&lt;T&gt; </em>is
enormously helpful in such a scenario.
</p>
        <p>
The key file of the sample code – the implementation of the queue itself aside – is
obviously Program.cs. Here’s Main() :
</p>
        <div class="csharpcode">
          <pre class="alt">
            <span class="kwrd">static</span>
            <span class="kwrd">void</span> Main(<span class="kwrd">string</span>[]
args)</pre>
          <pre>{</pre>
          <pre class="alt">
            <span class="kwrd">int</span> maxItemsInQueue = 10;</pre>
          <pre>    InputQueue&lt;IPAddress&gt; logDataQueue = <span class="kwrd">new</span> InputQueue&lt;IPAddress&gt;();</pre>
          <pre class="alt">
            <span class="kwrd">int</span> numResolverLoops = 20;</pre>
          <pre>    ManualResetEvent shutdownCompleteEvent = <span class="kwrd">new</span> ManualResetEvent(<span class="kwrd">false</span>);</pre>
          <pre class="alt">    List&lt;IPAddressResolverLoop&gt; resolverLoops = <span class="kwrd">new</span> List&lt;IPAddressResolverLoop&gt;();</pre>
          <pre> </pre>
          <pre class="alt">    Console.WriteLine(<span class="str">"You can stop the program
by pressing ENTER."</span>);</pre>
        </div>
        <style type="text/css">

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
We’re setting up a new <em>InputQueue&lt;IPAddress&gt;</em> here into which we’ll
throw the parsed addresses from our acquisition loop that simulates reading from the
log. The queue’s capacity will be limited to just 10 entries (<em>maxItemsInQueue</em> is
the input value) and we will run 20 'resolver loops’, which are logical threads that
process IP-to-hostname resolution steps.
</p>
        <div class="csharpcode">
          <pre class="alt">    Console.WriteLine(<span class="str">"You
can stop the program by pressing ENTER."</span>);</pre>
          <pre> </pre>
          <pre class="alt">
            <span class="rem">// set up the loop termination callback</span>
          </pre>
          <pre>    WaitCallback loopTerminationCallback = o =&gt;</pre>
          <pre class="alt">    {</pre>
          <pre>
            <span class="kwrd">if</span> (Interlocked.Decrement(<span class="kwrd">ref</span> numResolverLoops)
== 0)</pre>
          <pre class="alt">        {</pre>
          <pre>            shutdownCompleteEvent.Set();</pre>
          <pre class="alt">        }</pre>
          <pre>    };</pre>
          <pre class="alt"> </pre>
          <pre>
            <span class="rem">// set up the resolver loops</span>
          </pre>
          <pre class="alt">
            <span class="kwrd">for</span> (<span class="kwrd">int</span> loop
= 0; loop &lt; numResolverLoops; loop++)</pre>
          <pre>    {</pre>
          <pre class="alt">
            <span class="rem">// add the resolver loop 'i' and set the
done flag when the</span>
          </pre>
          <pre>
            <span class="rem">// last of them terminates</span>
          </pre>
          <pre class="alt">        resolverLoops.Add(</pre>
          <pre>
            <span class="kwrd">new</span> IPAddressResolverLoop(</pre>
          <pre class="alt">                logDataQueue, loop, </pre>
          <pre>                loopTerminationCallback, <span class="kwrd">null</span>));</pre>
          <pre class="alt">    }</pre>
        </div>
        <p>
Next we’re kicking off the resolver loops – we’ll look at these in detail a bit later.
We’ve got a <em>ManualResetEvent</em> lock object that guards the program’s exit until
all these loops have completed and we’re going to set that to signaled once the last
loop completes – that’s what the <em>loopTerminationCallback</em> anonymous method
is for.  We’re registering the method with each of the loops and as they complete
the method gets called and the last call sets the event. Each loop gets a reference
to the <em>logDataQueue </em>from where it gets its work.
</p>
        <div class="csharpcode">
          <pre class="alt">   <span class="rem">// set up
the acquisition loop; the loop auto-starts</span></pre>
          <pre>
            <span class="kwrd">using</span> (LogDataAcquisitionLoop acquisitionLoop =</pre>
          <pre class="alt">
            <span class="kwrd">new</span> LogDataAcquisitionLoop(logDataQueue,
maxItemsInQueue))</pre>
          <pre>    {</pre>
          <pre class="alt">
            <span class="rem">// hang main thread waiting for ENTER</span>
          </pre>
          <pre>        Console.ReadLine();</pre>
          <pre class="alt">        Console.WriteLine(<span class="str">"*** Shutdown initiated."</span>);</pre>
          <pre>    }</pre>
        </div>
        <style type="text/css">

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
Finally we’re starting the acquisition loop that gets the data from the log file.
The loop gets a reference to the <em>logDataQueue</em> where it places the acquired
items and it’s passed the <em>maxItemsInQueue </em>quota that governs how many items
may be read ahead into the queue. Once the user presses the ENTER key, the acquisition
loop object is disposed by ways of exiting the <em>using</em> scope, which stops the
loop.
</p>
        <div class="csharpcode">
          <pre class="alt">
            <span class="rem"> // shut down the queue;
the resolvers will auto-close</span>
          </pre>
          <pre>
            <span class="rem">// as the queue drains. We don't need to close them here.</span>
          </pre>
          <pre class="alt">    logDataQueue.Shutdown();</pre>
          <pre> </pre>
          <pre class="alt">
            <span class="rem">// wait for all work to complete</span>
          </pre>
          <pre>    shutdownCompleteEvent.WaitOne();</pre>
          <pre class="alt">}</pre>
        </div>
        <style type="text/css">

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
Lastly, the queue is shut down (by fittingly calling <em>Shutdown</em>). Shutdown
closes the queue (all further enqueue operations are absorbed) and causes all pending
readers for which no more entries are available on the queue to unblock immediately 
and return <em>null</em>. The resolver loops will complete their respective jobs and
will terminate whenever they dequeue <em>null</em> from the queue. As they terminate,
they call the registered termination callback (<em>loopTerminationCallback</em> from
above) and that will eventually cause <em>shutdownCompletedEvent</em> to become signaled
as discussed above.
</p>
        <p>
The log-reader simulator isn’t particularly interesting for this sample, even though
one of the goodies is that the simulation executes on an I/O completion port instead
of a managed thread-pool thread – that’s another blog post. The two methods of interest
are Begin/EndGetLogData – all that’s of interest here is that EndGetLogData returns
an <em>IPAddress</em> that’s assumed to be parsed out of a log.
</p>
        <div class="csharpcode">
          <pre class="alt">
            <span class="kwrd">class</span> IPAddressLogReaderSimulator</pre>
          <pre>{</pre>
          <pre class="alt">
            <span class="kwrd">public</span> IAsyncResult BeginGetLogData(AsyncCallback
callback, <span class="kwrd">object</span> data);</pre>
          <pre>
            <span class="kwrd">public</span> IPAddress EndGetLogData(IAsyncResult result);</pre>
          <pre class="alt">}</pre>
        </div>
        <style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
The simulator is used internally  by the <em>LogDataAcquisitionLoop</em> class
– which we’ll drill into because it implements the throttling mechanism on the queue.
</p>
        <div class="csharpcode">
          <pre class="alt">
            <span class="kwrd">class</span> LogDataAcquisitionLoop
: IDisposable</pre>
          <pre>{</pre>
          <pre class="alt">
            <span class="kwrd">readonly</span> IPAddressLogReaderSimulator
ipAddressLogReaderSimulator;</pre>
          <pre>
            <span class="kwrd">readonly</span> InputQueue&lt;IPAddress&gt; logDataQueue;</pre>
          <pre class="alt">
            <span class="kwrd">int</span> maxItemsInQueue;</pre>
          <pre>
            <span class="kwrd">int</span> readingSuspended;</pre>
          <pre class="alt">
            <span class="kwrd">bool</span> shuttingDown;</pre>
          <pre> </pre>
          <pre class="alt">
            <span class="kwrd">public</span> LogDataAcquisitionLoop(InputQueue&lt;IPAddress&gt;
logDataQueue, <span class="kwrd">int</span> maxItemsInQueue)</pre>
          <pre>    {</pre>
          <pre class="alt">
            <span class="kwrd">this</span>.logDataQueue = logDataQueue;</pre>
          <pre>
            <span class="kwrd">this</span>.maxItemsInQueue = maxItemsInQueue;</pre>
          <pre class="alt">
            <span class="kwrd">this</span>.shuttingDown = <span class="kwrd">false</span>;</pre>
          <pre>
            <span class="kwrd">this</span>.ipAddressLogReaderSimulator = <span class="kwrd">new</span> IPAddressLogReaderSimulator();</pre>
          <pre class="alt">
            <span class="kwrd">this</span>.ipAddressLogReaderSimulator.BeginGetLogData(<font style="BACKGROUND-COLOR: #ffff00"><span class="kwrd">this</span>.LogDataAcquired</font>, <span class="kwrd">null</span>);</pre>
          <pre>    }</pre>
        </div>
        <style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
The constructor sets up the shared state of the loop and kicks off the first read
operation on the simulator. Once BeginGetLogData has acquired the first IPAddress
(which will happy very quickly), the <em>LogDataAcquired</em> callback method will
be invoked.  
</p>
        <div class="csharpcode">
          <pre class="alt">
            <span class="kwrd">void</span>
            <font style="BACKGROUND-COLOR: #ffff00">LogDataAcquired</font>(IAsyncResult
result)</pre>
          <pre>    {</pre>
          <pre class="alt">        IPAddress address = <span class="kwrd">this</span>.ipAddressLogReaderSimulator.EndGetLogData(result);</pre>
          <pre> </pre>
          <pre class="alt">        Console.WriteLine(<span class="str">"-- added {0}"</span>,
address);</pre>
          <pre>
            <span class="kwrd">this</span>.logDataQueue.EnqueueAndDispatch(address, <span class="kwrd">this</span>.<font style="BACKGROUND-COLOR: #00ff00">LogDataItemDequeued</font>);</pre>
          <pre class="alt">
            <span class="kwrd">if</span> (!<span class="kwrd">this</span>.shuttingDown
&amp;&amp; <span class="kwrd">this</span>.logDataQueue.PendingCount &lt; <span class="kwrd">this</span>.maxItemsInQueue)</pre>
          <pre>        {</pre>
          <pre class="alt">
            <span class="kwrd">this</span>.ipAddressLogReaderSimulator.BeginGetLogData(<span class="kwrd">this</span>.<font style="BACKGROUND-COLOR: #ffff00">LogDataAcquired</font>, <span class="kwrd">null</span>);</pre>
          <pre>        }</pre>
          <pre class="alt">
            <span class="kwrd">else</span>
          </pre>
          <pre>        {</pre>
          <pre class="alt">
            <span class="rem">// the queue will be at the defined
capacity, thus abandon </span>
          </pre>
          <pre>
            <span class="rem">// the read loop - it'll be picked up by LogDataItemDequeued</span>
          </pre>
          <pre class="alt">
            <span class="rem">// as the queue pressure eases</span>
          </pre>
          <pre>            Interlocked.Exchange(<span class="kwrd">ref</span><span class="kwrd">this</span>.<font style="BACKGROUND-COLOR: #ffc000">readingSuspended</font>,
1);</pre>
          <pre class="alt">            Console.WriteLine(<span class="str">"-- suspended reads"</span>);</pre>
          <pre>        }</pre>
          <pre class="alt">    }</pre>
        </div>
        <style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
The callback method gets the IPAddress and puts it into the queue – using the <em>InputQueue&lt;T&gt;.EnqueueAndDispatch(T,
Action)</em> method. There are two aspects that are quite special about that method
when compared to the regular <em>Queue&lt;T&gt;.Enqueue(T) </em>method. First, it
does take a callback as the second argument alongside the item to be enqueued; second,
the method name isn’t just <em>Enqueue</em>, it also says <em>Dispatch. </em></p>
        <p>
When <em>EnqueueAndDispatch()</em> is called, the item and the callback get put into
an internal item queue – that’s the ‘enqueue’ part. As we will see in context a bit
later in this post, the ‘dequeue’ operation on the queue is the <em>BeginDequeue</em>/<em>EndDequeue</em> asynchronous
method call pair. There can be any number of concurrent <em>BeginDequeue</em> requests
pending on the queue. ‘Pending’ means that the calls – rather their async callbacks
and async state – are registered in another queue internal to <em>InputQueue&lt;T&gt;</em> that
preserves the call order. Thus, <em>BeginDequeue </em>always only puts the async callback
and async state into that queue and returns afterwards. There is no thread spun or
hung. That’s all it does.  
</p>
        <p>
As things go, the best opportunity to service a pending dequeue operation on a queue
is when an item is being enqueued. Consequently, <em>EnqueueAndDispatch()</em> will
first put the item into the internal queue and will then look whether there are registered
waiters and/or readers – waiters are registered by ‘(Begin-)WaitForItem’, readers
are registered by ‘(Begin-)Dequeue’. Since it’s known that there a new item in the
queue now, the operation will iterate overall waiters and complete them – and does
so by invoking their async callbacks, effectively lending the  enqueue operation’s
thread to the waiters. If there’s at least one pending reader, it’ll then pop a message
from the head of the internal item queue and call the reader’s async callback, lending
the enqueue operation’s thread to processing of the dequeue operation. If that just
made your head spin – yes, the item may have been dequeued and processed as <em>EnqueueAndDispatch</em> returns. 
</p>
        <p>
There is an overload for<em> EnqueueAndDispatch()</em> that takes an extra boolean
parameter that lets you cause the dispatch operation to happen on a different thread,
and there is also a <em>EnqueueWithoutDispatch()</em> method that just won’t dispatch
through and a standalone <em>Dispatch()</em> method.  
</p>
        <p>
The callback supplied to <em>EnqueueAndDispatch()</em>, here the <em>LogDataItemDequeued</em> method,
is am <em>Action </em>delegate. The queue will call this callback as the item is being
dequeued and, more precisely, when the item has been removed from the internal item
queue, but just before it is returned to the caller. That turns out to be quite handy.
If you take another look at the <font style="BACKGROUND-COLOR: #ffff00"><em>LogDataAcquired</em></font> method
you’ll notice that we’ve got two alternate code paths after <em>EnqueueAndDispatch()</em>.
The first branch is called when the queue has not reached capacity and it’s not shutting
down. When that’s so, we’re scheduling getting the next log item – otherwise we don’t.
Instead, we set the <em><font style="BACKGROUND-COLOR: #ffffff">readingSuspended</font></em> flag
and quit – effectively terminating and abandoning the loop. So how does that get restarted
when the queue is no longer at capacity? The <em>LogDataItemDequeued</em> callback!
</p>
        <div class="csharpcode">
          <pre class="alt">
            <span class="kwrd">void</span>
            <font style="BACKGROUND-COLOR: #00ff00">LogDataItemDequeued</font>()</pre>
          <pre>    {</pre>
          <pre class="alt">
            <span class="rem">// called whenever an item is dequeued.
First we check </span>
          </pre>
          <pre>
            <span class="rem">// whether the queue is no longer full after this </span>
          </pre>
          <pre class="alt">
            <span class="rem">// operation and the we check whether we
need to resume</span>
          </pre>
          <pre>
            <span class="rem">// the read loop.</span>
          </pre>
          <pre class="alt">
            <span class="kwrd">if</span> (!<span class="kwrd">this</span>.shuttingDown
&amp;&amp;</pre>
          <pre>
            <span class="kwrd">this</span>.logDataQueue.PendingCount &lt; <span class="kwrd">this</span>.maxItemsInQueue
&amp;&amp;</pre>
          <pre class="alt">            Interlocked.CompareExchange(<span class="kwrd">ref</span><span class="kwrd">this</span>.readingSuspended,
0, 1) == 1)</pre>
          <pre>        {</pre>
          <pre class="alt">            Console.WriteLine(<span class="str">"-- resuming reads"</span>);</pre>
          <pre>
            <span class="kwrd">this</span>.ipAddressLogReaderSimulator.BeginGetLogData(<span class="kwrd">this</span>.LogDataAcquired, <span class="kwrd">null</span>);</pre>
          <pre class="alt">        }</pre>
          <pre>    }</pre>
        </div>
        <style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
The callback gets called for each item that gets dequeued. Which means that we’ll
get an opportunity to restart the loop when it’s been stalled because the queue reached
capacity. So we’re checking here whether the queue isn’t shuttong down and whether
it’s below capacity and if that’s so and the <em>readingSuspended</em> flag is set,
we’re  restarting the read loop. And that’s how the throttle works.
</p>
        <p>
So now we’ve got the data from the log in the queue and we’re throttling nicely so
that we don’t pull too much data into memory. How about taking a look at the DNS resolver
loops that process the data?
</p>
        <div class="csharpcode">
          <pre class="alt">
            <span class="kwrd">class</span> IPAddressResolverLoop
: IDisposable</pre>
          <pre>{</pre>
          <pre class="alt">
            <span class="kwrd">readonly</span> InputQueue&lt;IPAddress&gt;
logDataQueue;</pre>
          <pre>
            <span class="kwrd">readonly</span>
            <span class="kwrd">int</span> loop;</pre>
          <pre class="alt">
            <span class="kwrd">readonly</span> WaitCallback loopCompleted;</pre>
          <pre>
            <span class="kwrd">readonly</span>
            <span class="kwrd">object</span> state;</pre>
          <pre class="alt">
            <span class="kwrd">bool</span> shutdown;</pre>
          <pre> </pre>
          <pre class="alt">
            <span class="kwrd">public</span> IPAddressResolverLoop(InputQueue&lt;IPAddress&gt;
logDataQueue, <span class="kwrd">int</span> loop, WaitCallback loopCompleted, <span class="kwrd">object</span> state)</pre>
          <pre>    {</pre>
          <pre class="alt">
            <span class="kwrd">this</span>.logDataQueue = logDataQueue;</pre>
          <pre>
            <span class="kwrd">this</span>.loop = loop;</pre>
          <pre class="alt">
            <span class="kwrd">this</span>.loopCompleted = loopCompleted;</pre>
          <pre>
            <span class="kwrd">this</span>.state = state;</pre>
          <pre class="alt">
            <span class="kwrd">this</span>.logDataQueue.BeginDequeue(TimeSpan.MaxValue, <span class="kwrd">this</span>.<font style="BACKGROUND-COLOR: #ffff00">IPAddressDequeued</font>, <span class="kwrd">null</span>);</pre>
          <pre>    }</pre>
        </div>
        <style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
This loop is also implemented as a class and the fields hold shared that that’s initialized
in the constructor. This loop also auto-starts and does so by calling <em>BeginDequeue </em>on
the input queue. As stated above, BeginDequeue  commonly just parks the callback
and returns.
</p>
        <div class="csharpcode">
          <pre class="alt">
            <span class="kwrd">void</span>
            <font style="BACKGROUND-COLOR: #ffff00">IPAddressDequeued</font>(IAsyncResult
ar)</pre>
          <pre>    {</pre>
          <pre class="alt">        IPAddress address = <span class="kwrd">this</span>.logDataQueue.EndDequeue(ar);</pre>
          <pre>
            <span class="kwrd">if</span> (!<span class="kwrd">this</span>.shutdown
&amp;&amp; address != <span class="kwrd">null</span>)</pre>
          <pre class="alt">        {</pre>
          <pre>            Console.WriteLine(<span class="str">"-- took {0}"</span>, address);</pre>
          <pre class="alt">            Dns.BeginGetHostEntry(address, <span class="kwrd">this</span>.<font style="BACKGROUND-COLOR: #00ff00">IPAddressResolved</font>, <span class="kwrd">new</span><span class="kwrd">object</span>[]
{ Stopwatch.StartNew(), address });</pre>
          <pre>        }</pre>
          <pre class="alt">
            <span class="kwrd">else</span>
          </pre>
          <pre>        {</pre>
          <pre class="alt">
            <span class="kwrd">this</span>.loopCompleted(<span class="kwrd">this</span>.state);</pre>
          <pre>        }</pre>
          <pre class="alt">    }</pre>
        </div>
        <p>
As an <em>IPAddress</em> is becomes available on the queue, the callback is being
invoked and that’s quite likely on a thread lent by <em>EnqueueAndDispatch</em>()
and therefore sitting  on the thread the log file generator is using to call
back for completion of the <em>BeginGetLogData</em> method if you trace things back.
If we get an address and the value isn’t <em>null</em>, we’ll then proceed to schedule
the DNS lookup via <em>Dns.BeginGetHostEntry</em>. Otherwise we’ll terminate the loop
and call the <em>loopCompleted</em> callback. In Main() that’s the anonymous method
that counts down the loop counter and signals the event when it falls to zero.
</p>
        <div class="csharpcode">
          <pre class="alt">
            <span class="kwrd">void</span>
            <font style="BACKGROUND-COLOR: #00ff00">IPAddressResolved</font>(IAsyncResult
ar)</pre>
          <pre>    {</pre>
          <pre class="alt">        var args = ((<span class="kwrd">object</span>[])ar.AsyncState);</pre>
          <pre>        var stopwatch = (Stopwatch)args[0];</pre>
          <pre class="alt">        var address = (IPAddress)args[1];</pre>
          <pre> </pre>
          <pre class="alt">        stopwatch.Stop();</pre>
          <pre>
            <span class="kwrd">double</span> msecs = stopwatch.ElapsedMilliseconds;</pre>
          <pre class="alt"> </pre>
          <pre>
            <span class="kwrd">try</span>
          </pre>
          <pre class="alt">        {</pre>
          <pre>            IPHostEntry entry = Dns.EndGetHostEntry(ar);</pre>
          <pre class="alt">            Console.WriteLine(<span class="str">"{0}: {1} {2}ms"</span>, <span class="kwrd">this</span>.loop,
entry.HostName, msecs);</pre>
          <pre>        }</pre>
          <pre class="alt">
            <span class="kwrd">catch</span> (SocketException)</pre>
          <pre>        {</pre>
          <pre class="alt">
            <span class="rem">// couldn't resolve. print the literal
address</span>
          </pre>
          <pre>            Console.WriteLine(<span class="str">"{0}: {1} {2}ms"</span>, <span class="kwrd">this</span>.loop,
address, msecs);</pre>
          <pre class="alt">        }</pre>
          <pre>
            <span class="rem">// done with this entry, get the next</span>
          </pre>
          <pre class="alt">
            <span class="kwrd">this</span>.logDataQueue.BeginDequeue(TimeSpan.MaxValue, <span class="kwrd">this</span>.<font style="BACKGROUND-COLOR: #ffff00">IPAddressDequeued</font>, <span class="kwrd">null</span>);</pre>
          <pre>    }</pre>
        </div>
        <style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
The <em>IPAddressResolved</em> method just deals with the mechanics of printing out
the result of the lookup and then schedules another <em>BeginDequeue</em> call to
start the next iteration. 
</p>
        <p>
Summary: The enabler for and the core piece of the implementation of this scenario
is <em>InputQueue&lt;T&gt;</em> – the dequeue-callback enables implementing throttling
effectively and the dispatch logic provides an efficient way to leverage threads in
applications that leverage asynchronous programming patterns, especially in I/O driven
situations as illustrated here.
</p>
        <p>
And last but not least – here’s teh codez; project file is for VS2010, throw the files
into a new console app for VS2008 and mark the project to allow unsafe code (for the
I/O completion thread pool code).
</p>
        <p>
          <a href="http://vasters.com/clemensv/content/binary/UsingInputQueue.zip">UsingInputQueue.zip
(13.85 KB)</a> 
</p>
        <p>
or if you'd rather have a version of InputQueue that is using the regular thread pool, <a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=35ec8682-d5fd-4bc3-a51a-d8ad115a8792&amp;displaylang=en">download
the WCF samples</a> and look for InputQueue.cs.
</p>
        <p>
[The sample code posted here is subject to the Windows SDK sample code license]
</p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=3d2486d4-2bfa-446c-886b-bf336f92c861" />
      </body>
      <title>The Magical Input Queue Of T (aka InputQueue&amp;lt;T&amp;gt;)</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,3d2486d4-2bfa-446c-886b-bf336f92c861.aspx</guid>
      <link>http://vasters.com/clemensv/2010/09/12/The+Magical+Input+Queue+Of+T+Aka+InputQueueltTgt.aspx</link>
      <pubDate>Sun, 12 Sep 2010 07:29:23 GMT</pubDate>
      <description>&lt;blockquote&gt; 
&lt;p&gt;
&lt;em&gt;This post explains an essential class for asynchronous programming that lurks
in the depths of the WCF samples: InputQueue&amp;lt;T&amp;gt;. If you need to write efficient
server-side apps, you should consider reading through this and add InputQueue&amp;lt;T&amp;gt;
to your arsenal.&amp;nbsp; &lt;/em&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Let me start with: This blog post is 4 years late. Sorry! – and with that out of the
way:
&lt;/p&gt;
&lt;p&gt;
The &lt;a href="http://msdn.microsoft.com/wcf"&gt;WCF&lt;/a&gt; samples ship with several copies
of a class that’s marked as internal in the &lt;em&gt;System.ServiceModel.dll&lt;/em&gt; assembly: &lt;em&gt;InputQueue&amp;lt;T&amp;gt;&lt;/em&gt;.
Why are these samples – mostly those implementing channel-model extensions – bringing
local copies of this class with them? It’s an essential tool for implementing the
asynchronous call paths of many aspects of channels correctly and efficiently. 
&lt;/p&gt;
&lt;p&gt;
If you look closely enough, the WCF channel infrastructure resembles the Berkeley
Socket model quite a bit – especially on the server side. There’s a channel listener
that’s constructed on the server side and when that is &lt;a href="http://msdn.microsoft.com/en-us/library/ms195524.aspx"&gt;opened&lt;/a&gt; (usually
under the covers of the WCF ServiceHost) that operation is largely equivalent to calling
‘listen’ on a socket – the network endpoint is ready for business.&amp;nbsp; On sockets
you’ll then call ‘accept’ to accept the next available socket connection from a client,
in WCF you call ‘&lt;a href="http://msdn.microsoft.com/en-us/library/ms195572.aspx"&gt;AcceptChannel&lt;/a&gt;’
to accept the next available (session-) channel. On sockets you then call ‘receive’
to obtain bytes, on a channel you call ’&lt;a href="http://msdn.microsoft.com/en-us/library/ms195339.aspx"&gt;Receive&lt;/a&gt;’
to&amp;nbsp; obtain a message. 
&lt;/p&gt;
&lt;p&gt;
Before and between calls to '’AcceptChannel’ made by the server-side logic,&amp;nbsp;
client-initiated connections – and thus channels – may be coming in and queue up for
a bit before they handed out to the next caller of ‘AcceptChannel’, or the asynchronous
equivalent ‘Begin/EndAcceptChannel’ method pair. The number of channels that may be
pending is configured in WCF with the ‘&lt;a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.nettcpbinding.listenbacklog.aspx"&gt;ListenBacklog&lt;/a&gt;’
property that’s available on most bindings. 
&lt;/p&gt;
&lt;p&gt;
I wrote ‘queue up’ there since that’s precisely what happens – those newly created
channels on top of freshly accepted sockets or HTTP request channels are enqueued
into an &lt;em&gt;InputQueue&amp;lt;T&amp;gt;&lt;/em&gt; instance and (Begin-)Accept is implemented as
a dequeue operation on that queue. There are two particular challenges here that make
the regular &lt;em&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/7977ey2c.aspx"&gt;Queue&amp;lt;T&amp;gt;&lt;/a&gt;&lt;/em&gt; class
from the &lt;em&gt;System.Collections.Generic&lt;/em&gt; namespace unsuitable for use in the implementation
of that mechanism: Firstly, the &lt;a href="http://msdn.microsoft.com/en-us/library/1c8bzx97.aspx"&gt;&lt;em&gt;Dequeue&lt;/em&gt;&lt;/a&gt; method
there is only available as a synchronous variant and also doesn’t allow for specifying
a timeout. Secondly, the queue implementation doesn’t really help much with implementing
the &lt;em&gt;ListenBacklog&lt;/em&gt; quota where not only the length of the queue is limited
to some configured number of entries, but accepting further connections/channels from
the underlying network is also suspended for as long as the queue is at capacity and
needs to resume as soon as the pressure is relieved, i.e. a caller takes a channel
out of the queue. 
&lt;/p&gt;
&lt;p&gt;
To show that &lt;em&gt;InputQueue&amp;lt;T&amp;gt;&lt;/em&gt; is a very useful general purpose class even
outside of the context of the WCF channel infrastructure, I’ve lifted a version of
it from one of the most recent WCF channel samples, made a small number of modifications
that I’ll write about later, and created a little sample around it that I’ve attached
to this post. 
&lt;/p&gt;
&lt;p&gt;
The sample I’ll discuss here is simulating parsing/reading IP addresses from a log-file
and then performing a reverse DNS name resolution on those addresses – something that
you’d do in a web-server log-analyzer or as the background task in a blog engine wile
preparing statistics. 
&lt;/p&gt;
&lt;p&gt;
Reverse DNS name resolution is quite interesting since it’s embarrassingly easy to
parallelize and each resolution commonly takes a really long time (4-5 seconds) –whereby
all the work is done elsewhere. The process issuing the queries is mostly sitting
around idle waiting for the response.&amp;nbsp; Therefore, it’s a good idea to run a number
of DNS requests in parallel, but it’s a terrible idea to have any of these requests
execute as a blocking call and burning a thread. Since we’re assuming that we’re reading
from a log file that requires some parsing, it would also be a spectacularly bad idea
to have multiple concurrent threads compete for access to that file and get into each
other’s way. And since it is a file and we need to lift things up from disk, we probably
shouldn’t do that ‘just in time’ as a DNS resolution step is done, but there should
rather be some data readily waiting for processing.&amp;nbsp; &lt;em&gt;InputQueue&amp;lt;T&amp;gt; &lt;/em&gt;is
enormously helpful in such a scenario.
&lt;/p&gt;
&lt;p&gt;
The key file of the sample code – the implementation of the queue itself aside – is
obviously Program.cs. Here’s Main() :
&lt;/p&gt;
&lt;div class=csharpcode&gt;&lt;pre class=alt&gt;&lt;span class=kwrd&gt;static&lt;/span&gt; &lt;span class=kwrd&gt;void&lt;/span&gt; Main(&lt;span class=kwrd&gt;string&lt;/span&gt;[]
args)&lt;/pre&gt;
&lt;pre&gt;{&lt;/pre&gt;
&lt;pre class=alt&gt;    &lt;span class=kwrd&gt;int&lt;/span&gt; maxItemsInQueue = 10;&lt;/pre&gt;
&lt;pre&gt;    InputQueue&amp;lt;IPAddress&amp;gt; logDataQueue = &lt;span class=kwrd&gt;new&lt;/span&gt; InputQueue&amp;lt;IPAddress&amp;gt;();&lt;/pre&gt;
&lt;pre class=alt&gt;    &lt;span class=kwrd&gt;int&lt;/span&gt; numResolverLoops = 20;&lt;/pre&gt;
&lt;pre&gt;    ManualResetEvent shutdownCompleteEvent = &lt;span class=kwrd&gt;new&lt;/span&gt; ManualResetEvent(&lt;span class=kwrd&gt;false&lt;/span&gt;);&lt;/pre&gt;
&lt;pre class=alt&gt;    List&amp;lt;IPAddressResolverLoop&amp;gt; resolverLoops = &lt;span class=kwrd&gt;new&lt;/span&gt; List&amp;lt;IPAddressResolverLoop&amp;gt;();&lt;/pre&gt;
&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class=alt&gt;    Console.WriteLine(&lt;span class=str&gt;"You can stop the program by
pressing ENTER."&lt;/span&gt;);&lt;/pre&gt;
&lt;/div&gt;
&lt;style type=text/css&gt;

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;p&gt;
We’re setting up a new &lt;em&gt;InputQueue&amp;lt;IPAddress&amp;gt;&lt;/em&gt; here into which we’ll
throw the parsed addresses from our acquisition loop that simulates reading from the
log. The queue’s capacity will be limited to just 10 entries (&lt;em&gt;maxItemsInQueue&lt;/em&gt; is
the input value) and we will run 20 'resolver loops’, which are logical threads that
process IP-to-hostname resolution steps.
&lt;/p&gt;
&lt;div class=csharpcode&gt;&lt;pre class=alt&gt;    Console.WriteLine(&lt;span class=str&gt;"You can
stop the program by pressing ENTER."&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class=alt&gt;    &lt;span class=rem&gt;// set up the loop termination callback&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;    WaitCallback loopTerminationCallback = o =&amp;gt;&lt;/pre&gt;
&lt;pre class=alt&gt;    {&lt;/pre&gt;
&lt;pre&gt;        &lt;span class=kwrd&gt;if&lt;/span&gt; (Interlocked.Decrement(&lt;span class=kwrd&gt;ref&lt;/span&gt; numResolverLoops)
== 0)&lt;/pre&gt;
&lt;pre class=alt&gt;        {&lt;/pre&gt;
&lt;pre&gt;            shutdownCompleteEvent.Set();&lt;/pre&gt;
&lt;pre class=alt&gt;        }&lt;/pre&gt;
&lt;pre&gt;    };&lt;/pre&gt;
&lt;pre class=alt&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;    &lt;span class=rem&gt;// set up the resolver loops&lt;/span&gt;&lt;/pre&gt;
&lt;pre class=alt&gt;    &lt;span class=kwrd&gt;for&lt;/span&gt; (&lt;span class=kwrd&gt;int&lt;/span&gt; loop =
0; loop &amp;lt; numResolverLoops; loop++)&lt;/pre&gt;
&lt;pre&gt;    {&lt;/pre&gt;
&lt;pre class=alt&gt;        &lt;span class=rem&gt;// add the resolver loop 'i' and set the done
flag when the&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;        &lt;span class=rem&gt;// last of them terminates&lt;/span&gt;&lt;/pre&gt;
&lt;pre class=alt&gt;        resolverLoops.Add(&lt;/pre&gt;
&lt;pre&gt;            &lt;span class=kwrd&gt;new&lt;/span&gt; IPAddressResolverLoop(&lt;/pre&gt;
&lt;pre class=alt&gt;                logDataQueue, loop, &lt;/pre&gt;
&lt;pre&gt;                loopTerminationCallback, &lt;span class=kwrd&gt;null&lt;/span&gt;));&lt;/pre&gt;
&lt;pre class=alt&gt;    }&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
Next we’re kicking off the resolver loops – we’ll look at these in detail a bit later.
We’ve got a &lt;em&gt;ManualResetEvent&lt;/em&gt; lock object that guards the program’s exit until
all these loops have completed and we’re going to set that to signaled once the last
loop completes – that’s what the &lt;em&gt;loopTerminationCallback&lt;/em&gt; anonymous method
is for.&amp;nbsp; We’re registering the method with each of the loops and as they complete
the method gets called and the last call sets the event. Each loop gets a reference
to the &lt;em&gt;logDataQueue &lt;/em&gt;from where it gets its work.
&lt;/p&gt;
&lt;div class=csharpcode&gt;&lt;pre class=alt&gt;&amp;nbsp;&amp;nbsp; &lt;span class=rem&gt;// set up the acquisition
loop; the loop auto-starts&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;    &lt;span class=kwrd&gt;using&lt;/span&gt; (LogDataAcquisitionLoop acquisitionLoop =&lt;/pre&gt;
&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;new&lt;/span&gt; LogDataAcquisitionLoop(logDataQueue,
maxItemsInQueue))&lt;/pre&gt;
&lt;pre&gt;    {&lt;/pre&gt;
&lt;pre class=alt&gt;        &lt;span class=rem&gt;// hang main thread waiting for ENTER&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;        Console.ReadLine();&lt;/pre&gt;
&lt;pre class=alt&gt;        Console.WriteLine(&lt;span class=str&gt;"*** Shutdown initiated."&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;    }&lt;/pre&gt;
&lt;/div&gt;
&lt;style type=text/css&gt;

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;p&gt;
Finally we’re starting the acquisition loop that gets the data from the log file.
The loop gets a reference to the &lt;em&gt;logDataQueue&lt;/em&gt; where it places the acquired
items and it’s passed the &lt;em&gt;maxItemsInQueue &lt;/em&gt;quota that governs how many items
may be read ahead into the queue. Once the user presses the ENTER key, the acquisition
loop object is disposed by ways of exiting the &lt;em&gt;using&lt;/em&gt; scope, which stops the
loop.
&lt;/p&gt;
&lt;div class=csharpcode&gt;&lt;pre class=alt&gt;&lt;span class=rem&gt; // shut down the queue; the
resolvers will auto-close&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;    &lt;span class=rem&gt;// as the queue drains. We don't need to close them here.&lt;/span&gt;&lt;/pre&gt;
&lt;pre class=alt&gt;    logDataQueue.Shutdown();&lt;/pre&gt;
&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class=alt&gt;    &lt;span class=rem&gt;// wait for all work to complete&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;    shutdownCompleteEvent.WaitOne();&lt;/pre&gt;
&lt;pre class=alt&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;style type=text/css&gt;

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;p&gt;
Lastly, the queue is shut down (by fittingly calling &lt;em&gt;Shutdown&lt;/em&gt;). Shutdown
closes the queue (all further enqueue operations are absorbed) and causes all pending
readers for which no more entries are available on the queue to unblock immediately&amp;nbsp;
and return &lt;em&gt;null&lt;/em&gt;. The resolver loops will complete their respective jobs and
will terminate whenever they dequeue &lt;em&gt;null&lt;/em&gt; from the queue. As they terminate,
they call the registered termination callback (&lt;em&gt;loopTerminationCallback&lt;/em&gt; from
above) and that will eventually cause &lt;em&gt;shutdownCompletedEvent&lt;/em&gt; to become signaled
as discussed above.
&lt;/p&gt;
&lt;p&gt;
The log-reader simulator isn’t particularly interesting for this sample, even though
one of the goodies is that the simulation executes on an I/O completion port instead
of a managed thread-pool thread – that’s another blog post. The two methods of interest
are Begin/EndGetLogData – all that’s of interest here is that EndGetLogData returns
an &lt;em&gt;IPAddress&lt;/em&gt; that’s assumed to be parsed out of a log.
&lt;/p&gt;
&lt;div class=csharpcode&gt;&lt;pre class=alt&gt;&lt;span class=kwrd&gt;class&lt;/span&gt; IPAddressLogReaderSimulator&lt;/pre&gt;
&lt;pre&gt;{&lt;/pre&gt;
&lt;pre class=alt&gt;    &lt;span class=kwrd&gt;public&lt;/span&gt; IAsyncResult BeginGetLogData(AsyncCallback
callback, &lt;span class=kwrd&gt;object&lt;/span&gt; data);&lt;/pre&gt;
&lt;pre&gt;    &lt;span class=kwrd&gt;public&lt;/span&gt; IPAddress EndGetLogData(IAsyncResult result);&lt;/pre&gt;
&lt;pre class=alt&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;style type=text/css&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;p&gt;
The simulator is used internally&amp;nbsp; by the &lt;em&gt;LogDataAcquisitionLoop&lt;/em&gt; class
– which we’ll drill into because it implements the throttling mechanism on the queue.
&lt;/p&gt;
&lt;div class=csharpcode&gt;&lt;pre class=alt&gt;&lt;span class=kwrd&gt;class&lt;/span&gt; LogDataAcquisitionLoop
: IDisposable&lt;/pre&gt;
&lt;pre&gt;{&lt;/pre&gt;
&lt;pre class=alt&gt;    &lt;span class=kwrd&gt;readonly&lt;/span&gt; IPAddressLogReaderSimulator ipAddressLogReaderSimulator;&lt;/pre&gt;
&lt;pre&gt;    &lt;span class=kwrd&gt;readonly&lt;/span&gt; InputQueue&amp;lt;IPAddress&amp;gt; logDataQueue;&lt;/pre&gt;
&lt;pre class=alt&gt;    &lt;span class=kwrd&gt;int&lt;/span&gt; maxItemsInQueue;&lt;/pre&gt;
&lt;pre&gt;    &lt;span class=kwrd&gt;int&lt;/span&gt; readingSuspended;&lt;/pre&gt;
&lt;pre class=alt&gt;    &lt;span class=kwrd&gt;bool&lt;/span&gt; shuttingDown;&lt;/pre&gt;
&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class=alt&gt;    &lt;span class=kwrd&gt;public&lt;/span&gt; LogDataAcquisitionLoop(InputQueue&amp;lt;IPAddress&amp;gt;
logDataQueue, &lt;span class=kwrd&gt;int&lt;/span&gt; maxItemsInQueue)&lt;/pre&gt;
&lt;pre&gt;    {&lt;/pre&gt;
&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;this&lt;/span&gt;.logDataQueue = logDataQueue;&lt;/pre&gt;
&lt;pre&gt;        &lt;span class=kwrd&gt;this&lt;/span&gt;.maxItemsInQueue = maxItemsInQueue;&lt;/pre&gt;
&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;this&lt;/span&gt;.shuttingDown = &lt;span class=kwrd&gt;false&lt;/span&gt;;&lt;/pre&gt;
&lt;pre&gt;        &lt;span class=kwrd&gt;this&lt;/span&gt;.ipAddressLogReaderSimulator = &lt;span class=kwrd&gt;new&lt;/span&gt; IPAddressLogReaderSimulator();&lt;/pre&gt;
&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;this&lt;/span&gt;.ipAddressLogReaderSimulator.BeginGetLogData(&lt;font style="BACKGROUND-COLOR: #ffff00"&gt;&lt;span class=kwrd&gt;this&lt;/span&gt;.LogDataAcquired&lt;/font&gt;, &lt;span class=kwrd&gt;null&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;    }&lt;/pre&gt;
&lt;/div&gt;
&lt;style type=text/css&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;p&gt;
The constructor sets up the shared state of the loop and kicks off the first read
operation on the simulator. Once BeginGetLogData has acquired the first IPAddress
(which will happy very quickly), the &lt;em&gt;LogDataAcquired&lt;/em&gt; callback method will
be invoked.&amp;nbsp; 
&lt;/p&gt;
&lt;div class=csharpcode&gt;&lt;pre class=alt&gt;    &lt;span class=kwrd&gt;void&lt;/span&gt; &lt;font style="BACKGROUND-COLOR: #ffff00"&gt;LogDataAcquired&lt;/font&gt;(IAsyncResult
result)&lt;/pre&gt;
&lt;pre&gt;    {&lt;/pre&gt;
&lt;pre class=alt&gt;        IPAddress address = &lt;span class=kwrd&gt;this&lt;/span&gt;.ipAddressLogReaderSimulator.EndGetLogData(result);&lt;/pre&gt;
&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class=alt&gt;        Console.WriteLine(&lt;span class=str&gt;"-- added {0}"&lt;/span&gt;, address);&lt;/pre&gt;
&lt;pre&gt;        &lt;span class=kwrd&gt;this&lt;/span&gt;.logDataQueue.EnqueueAndDispatch(address, &lt;span class=kwrd&gt;this&lt;/span&gt;.&lt;font style="BACKGROUND-COLOR: #00ff00"&gt;LogDataItemDequeued&lt;/font&gt;);&lt;/pre&gt;
&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;if&lt;/span&gt; (!&lt;span class=kwrd&gt;this&lt;/span&gt;.shuttingDown
&amp;amp;&amp;amp; &lt;span class=kwrd&gt;this&lt;/span&gt;.logDataQueue.PendingCount &amp;lt; &lt;span class=kwrd&gt;this&lt;/span&gt;.maxItemsInQueue)&lt;/pre&gt;
&lt;pre&gt;        {&lt;/pre&gt;
&lt;pre class=alt&gt;            &lt;span class=kwrd&gt;this&lt;/span&gt;.ipAddressLogReaderSimulator.BeginGetLogData(&lt;span class=kwrd&gt;this&lt;/span&gt;.&lt;font style="BACKGROUND-COLOR: #ffff00"&gt;LogDataAcquired&lt;/font&gt;, &lt;span class=kwrd&gt;null&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;        }&lt;/pre&gt;
&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;else&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;        {&lt;/pre&gt;
&lt;pre class=alt&gt;            &lt;span class=rem&gt;// the queue will be at the defined capacity,
thus abandon &lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;            &lt;span class=rem&gt;// the read loop - it'll be picked up by LogDataItemDequeued&lt;/span&gt;&lt;/pre&gt;
&lt;pre class=alt&gt;            &lt;span class=rem&gt;// as the queue pressure eases&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;            Interlocked.Exchange(&lt;span class=kwrd&gt;ref&lt;/span&gt; &lt;span class=kwrd&gt;this&lt;/span&gt;.&lt;font style="BACKGROUND-COLOR: #ffc000"&gt;readingSuspended&lt;/font&gt;,
1);&lt;/pre&gt;
&lt;pre class=alt&gt;            Console.WriteLine(&lt;span class=str&gt;"-- suspended reads"&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;        }&lt;/pre&gt;
&lt;pre class=alt&gt;    }&lt;/pre&gt;
&lt;/div&gt;
&lt;style type=text/css&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;style type=text/css&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;p&gt;
The callback method gets the IPAddress and puts it into the queue – using the &lt;em&gt;InputQueue&amp;lt;T&amp;gt;.EnqueueAndDispatch(T,
Action)&lt;/em&gt; method. There are two aspects that are quite special about that method
when compared to the regular &lt;em&gt;Queue&amp;lt;T&amp;gt;.Enqueue(T) &lt;/em&gt;method. First, it
does take a callback as the second argument alongside the item to be enqueued; second,
the method name isn’t just &lt;em&gt;Enqueue&lt;/em&gt;, it also says &lt;em&gt;Dispatch. &lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
When &lt;em&gt;EnqueueAndDispatch()&lt;/em&gt; is called, the item and the callback get put into
an internal item queue – that’s the ‘enqueue’ part. As we will see in context a bit
later in this post, the ‘dequeue’ operation on the queue is the &lt;em&gt;BeginDequeue&lt;/em&gt;/&lt;em&gt;EndDequeue&lt;/em&gt; asynchronous
method call pair. There can be any number of concurrent &lt;em&gt;BeginDequeue&lt;/em&gt; requests
pending on the queue. ‘Pending’ means that the calls – rather their async callbacks
and async state – are registered in another queue internal to &lt;em&gt;InputQueue&amp;lt;T&amp;gt;&lt;/em&gt; that
preserves the call order. Thus, &lt;em&gt;BeginDequeue &lt;/em&gt;always only puts the async callback
and async state into that queue and returns afterwards. There is no thread spun or
hung. That’s all it does.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
As things go, the best opportunity to service a pending dequeue operation on a queue
is when an item is being enqueued. Consequently, &lt;em&gt;EnqueueAndDispatch()&lt;/em&gt; will
first put the item into the internal queue and will then look whether there are registered
waiters and/or readers – waiters are registered by ‘(Begin-)WaitForItem’, readers
are registered by ‘(Begin-)Dequeue’. Since it’s known that there a new item in the
queue now, the operation will iterate overall waiters and complete them – and does
so by invoking their async callbacks, effectively lending the&amp;nbsp; enqueue operation’s
thread to the waiters. If there’s at least one pending reader, it’ll then pop a message
from the head of the internal item queue and call the reader’s async callback, lending
the enqueue operation’s thread to processing of the dequeue operation. If that just
made your head spin – yes, the item may have been dequeued and processed as &lt;em&gt;EnqueueAndDispatch&lt;/em&gt; returns. 
&lt;/p&gt;
&lt;p&gt;
There is an overload for&lt;em&gt; EnqueueAndDispatch()&lt;/em&gt; that takes an extra boolean
parameter that lets you cause the dispatch operation to happen on a different thread,
and there is also a &lt;em&gt;EnqueueWithoutDispatch()&lt;/em&gt; method that just won’t dispatch
through and a standalone &lt;em&gt;Dispatch()&lt;/em&gt; method.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
The callback supplied to &lt;em&gt;EnqueueAndDispatch()&lt;/em&gt;, here the &lt;em&gt;LogDataItemDequeued&lt;/em&gt; method,
is am &lt;em&gt;Action &lt;/em&gt;delegate. The queue will call this callback as the item is being
dequeued and, more precisely, when the item has been removed from the internal item
queue, but just before it is returned to the caller. That turns out to be quite handy.
If you take another look at the &lt;font style="BACKGROUND-COLOR: #ffff00"&gt;&lt;em&gt;LogDataAcquired&lt;/em&gt;&lt;/font&gt; method
you’ll notice that we’ve got two alternate code paths after &lt;em&gt;EnqueueAndDispatch()&lt;/em&gt;.
The first branch is called when the queue has not reached capacity and it’s not shutting
down. When that’s so, we’re scheduling getting the next log item – otherwise we don’t.
Instead, we set the &lt;em&gt;&lt;font style="BACKGROUND-COLOR: #ffffff"&gt;readingSuspended&lt;/font&gt;&lt;/em&gt; flag
and quit – effectively terminating and abandoning the loop. So how does that get restarted
when the queue is no longer at capacity? The &lt;em&gt;LogDataItemDequeued&lt;/em&gt; callback!
&lt;/p&gt;
&lt;div class=csharpcode&gt;&lt;pre class=alt&gt;    &lt;span class=kwrd&gt;void&lt;/span&gt; &lt;font style="BACKGROUND-COLOR: #00ff00"&gt;LogDataItemDequeued&lt;/font&gt;()&lt;/pre&gt;
&lt;pre&gt;    {&lt;/pre&gt;
&lt;pre class=alt&gt;        &lt;span class=rem&gt;// called whenever an item is dequeued. First
we check &lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;        &lt;span class=rem&gt;// whether the queue is no longer full after this &lt;/span&gt;&lt;/pre&gt;
&lt;pre class=alt&gt;        &lt;span class=rem&gt;// operation and the we check whether we need
to resume&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;        &lt;span class=rem&gt;// the read loop.&lt;/span&gt;&lt;/pre&gt;
&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;if&lt;/span&gt; (!&lt;span class=kwrd&gt;this&lt;/span&gt;.shuttingDown
&amp;amp;&amp;amp;&lt;/pre&gt;
&lt;pre&gt;            &lt;span class=kwrd&gt;this&lt;/span&gt;.logDataQueue.PendingCount &amp;lt; &lt;span class=kwrd&gt;this&lt;/span&gt;.maxItemsInQueue
&amp;amp;&amp;amp;&lt;/pre&gt;
&lt;pre class=alt&gt;            Interlocked.CompareExchange(&lt;span class=kwrd&gt;ref&lt;/span&gt; &lt;span class=kwrd&gt;this&lt;/span&gt;.readingSuspended,
0, 1) == 1)&lt;/pre&gt;
&lt;pre&gt;        {&lt;/pre&gt;
&lt;pre class=alt&gt;            Console.WriteLine(&lt;span class=str&gt;"-- resuming reads"&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;            &lt;span class=kwrd&gt;this&lt;/span&gt;.ipAddressLogReaderSimulator.BeginGetLogData(&lt;span class=kwrd&gt;this&lt;/span&gt;.LogDataAcquired, &lt;span class=kwrd&gt;null&lt;/span&gt;);&lt;/pre&gt;
&lt;pre class=alt&gt;        }&lt;/pre&gt;
&lt;pre&gt;    }&lt;/pre&gt;
&lt;/div&gt;
&lt;style type=text/css&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;p&gt;
The callback gets called for each item that gets dequeued. Which means that we’ll
get an opportunity to restart the loop when it’s been stalled because the queue reached
capacity. So we’re checking here whether the queue isn’t shuttong down and whether
it’s below capacity and if that’s so and the &lt;em&gt;readingSuspended&lt;/em&gt; flag is set,
we’re&amp;nbsp; restarting the read loop. And that’s how the throttle works.
&lt;/p&gt;
&lt;p&gt;
So now we’ve got the data from the log in the queue and we’re throttling nicely so
that we don’t pull too much data into memory. How about taking a look at the DNS resolver
loops that process the data?
&lt;/p&gt;
&lt;div class=csharpcode&gt;&lt;pre class=alt&gt;&lt;span class=kwrd&gt;class&lt;/span&gt; IPAddressResolverLoop
: IDisposable&lt;/pre&gt;
&lt;pre&gt;{&lt;/pre&gt;
&lt;pre class=alt&gt;    &lt;span class=kwrd&gt;readonly&lt;/span&gt; InputQueue&amp;lt;IPAddress&amp;gt; logDataQueue;&lt;/pre&gt;
&lt;pre&gt;    &lt;span class=kwrd&gt;readonly&lt;/span&gt; &lt;span class=kwrd&gt;int&lt;/span&gt; loop;&lt;/pre&gt;
&lt;pre class=alt&gt;    &lt;span class=kwrd&gt;readonly&lt;/span&gt; WaitCallback loopCompleted;&lt;/pre&gt;
&lt;pre&gt;    &lt;span class=kwrd&gt;readonly&lt;/span&gt; &lt;span class=kwrd&gt;object&lt;/span&gt; state;&lt;/pre&gt;
&lt;pre class=alt&gt;    &lt;span class=kwrd&gt;bool&lt;/span&gt; shutdown;&lt;/pre&gt;
&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class=alt&gt;    &lt;span class=kwrd&gt;public&lt;/span&gt; IPAddressResolverLoop(InputQueue&amp;lt;IPAddress&amp;gt;
logDataQueue, &lt;span class=kwrd&gt;int&lt;/span&gt; loop, WaitCallback loopCompleted, &lt;span class=kwrd&gt;object&lt;/span&gt; state)&lt;/pre&gt;
&lt;pre&gt;    {&lt;/pre&gt;
&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;this&lt;/span&gt;.logDataQueue = logDataQueue;&lt;/pre&gt;
&lt;pre&gt;        &lt;span class=kwrd&gt;this&lt;/span&gt;.loop = loop;&lt;/pre&gt;
&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;this&lt;/span&gt;.loopCompleted = loopCompleted;&lt;/pre&gt;
&lt;pre&gt;        &lt;span class=kwrd&gt;this&lt;/span&gt;.state = state;&lt;/pre&gt;
&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;this&lt;/span&gt;.logDataQueue.BeginDequeue(TimeSpan.MaxValue, &lt;span class=kwrd&gt;this&lt;/span&gt;.&lt;font style="BACKGROUND-COLOR: #ffff00"&gt;IPAddressDequeued&lt;/font&gt;, &lt;span class=kwrd&gt;null&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;    }&lt;/pre&gt;
&lt;/div&gt;
&lt;style type=text/css&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;p&gt;
This loop is also implemented as a class and the fields hold shared that that’s initialized
in the constructor. This loop also auto-starts and does so by calling &lt;em&gt;BeginDequeue &lt;/em&gt;on
the input queue. As stated above, BeginDequeue&amp;nbsp; commonly just parks the callback
and returns.
&lt;/p&gt;
&lt;div class=csharpcode&gt;&lt;pre class=alt&gt;    &lt;span class=kwrd&gt;void&lt;/span&gt; &lt;font style="BACKGROUND-COLOR: #ffff00"&gt;IPAddressDequeued&lt;/font&gt;(IAsyncResult
ar)&lt;/pre&gt;
&lt;pre&gt;    {&lt;/pre&gt;
&lt;pre class=alt&gt;        IPAddress address = &lt;span class=kwrd&gt;this&lt;/span&gt;.logDataQueue.EndDequeue(ar);&lt;/pre&gt;
&lt;pre&gt;        &lt;span class=kwrd&gt;if&lt;/span&gt; (!&lt;span class=kwrd&gt;this&lt;/span&gt;.shutdown &amp;amp;&amp;amp;
address != &lt;span class=kwrd&gt;null&lt;/span&gt;)&lt;/pre&gt;
&lt;pre class=alt&gt;        {&lt;/pre&gt;
&lt;pre&gt;            Console.WriteLine(&lt;span class=str&gt;"-- took {0}"&lt;/span&gt;, address);&lt;/pre&gt;
&lt;pre class=alt&gt;            Dns.BeginGetHostEntry(address, &lt;span class=kwrd&gt;this&lt;/span&gt;.&lt;font style="BACKGROUND-COLOR: #00ff00"&gt;IPAddressResolved&lt;/font&gt;, &lt;span class=kwrd&gt;new&lt;/span&gt; &lt;span class=kwrd&gt;object&lt;/span&gt;[]
{ Stopwatch.StartNew(), address });&lt;/pre&gt;
&lt;pre&gt;        }&lt;/pre&gt;
&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;else&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;        {&lt;/pre&gt;
&lt;pre class=alt&gt;            &lt;span class=kwrd&gt;this&lt;/span&gt;.loopCompleted(&lt;span class=kwrd&gt;this&lt;/span&gt;.state);&lt;/pre&gt;
&lt;pre&gt;        }&lt;/pre&gt;
&lt;pre class=alt&gt;    }&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
As an &lt;em&gt;IPAddress&lt;/em&gt; is becomes available on the queue, the callback is being
invoked and that’s quite likely on a thread lent by &lt;em&gt;EnqueueAndDispatch&lt;/em&gt;()
and therefore sitting&amp;nbsp; on the thread the log file generator is using to call
back for completion of the &lt;em&gt;BeginGetLogData&lt;/em&gt; method if you trace things back.
If we get an address and the value isn’t &lt;em&gt;null&lt;/em&gt;, we’ll then proceed to schedule
the DNS lookup via &lt;em&gt;Dns.BeginGetHostEntry&lt;/em&gt;. Otherwise we’ll terminate the loop
and call the &lt;em&gt;loopCompleted&lt;/em&gt; callback. In Main() that’s the anonymous method
that counts down the loop counter and signals the event when it falls to zero.
&lt;/p&gt;
&lt;div class=csharpcode&gt;&lt;pre class=alt&gt;    &lt;span class=kwrd&gt;void&lt;/span&gt; &lt;font style="BACKGROUND-COLOR: #00ff00"&gt;IPAddressResolved&lt;/font&gt;(IAsyncResult
ar)&lt;/pre&gt;
&lt;pre&gt;    {&lt;/pre&gt;
&lt;pre class=alt&gt;        var args = ((&lt;span class=kwrd&gt;object&lt;/span&gt;[])ar.AsyncState);&lt;/pre&gt;
&lt;pre&gt;        var stopwatch = (Stopwatch)args[0];&lt;/pre&gt;
&lt;pre class=alt&gt;        var address = (IPAddress)args[1];&lt;/pre&gt;
&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class=alt&gt;        stopwatch.Stop();&lt;/pre&gt;
&lt;pre&gt;        &lt;span class=kwrd&gt;double&lt;/span&gt; msecs = stopwatch.ElapsedMilliseconds;&lt;/pre&gt;
&lt;pre class=alt&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;        &lt;span class=kwrd&gt;try&lt;/span&gt;&lt;/pre&gt;
&lt;pre class=alt&gt;        {&lt;/pre&gt;
&lt;pre&gt;            IPHostEntry entry = Dns.EndGetHostEntry(ar);&lt;/pre&gt;
&lt;pre class=alt&gt;            Console.WriteLine(&lt;span class=str&gt;"{0}: {1} {2}ms"&lt;/span&gt;, &lt;span class=kwrd&gt;this&lt;/span&gt;.loop,
entry.HostName, msecs);&lt;/pre&gt;
&lt;pre&gt;        }&lt;/pre&gt;
&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;catch&lt;/span&gt; (SocketException)&lt;/pre&gt;
&lt;pre&gt;        {&lt;/pre&gt;
&lt;pre class=alt&gt;            &lt;span class=rem&gt;// couldn't resolve. print the literal
address&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;            Console.WriteLine(&lt;span class=str&gt;"{0}: {1} {2}ms"&lt;/span&gt;, &lt;span class=kwrd&gt;this&lt;/span&gt;.loop,
address, msecs);&lt;/pre&gt;
&lt;pre class=alt&gt;        }&lt;/pre&gt;
&lt;pre&gt;        &lt;span class=rem&gt;// done with this entry, get the next&lt;/span&gt;&lt;/pre&gt;
&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;this&lt;/span&gt;.logDataQueue.BeginDequeue(TimeSpan.MaxValue, &lt;span class=kwrd&gt;this&lt;/span&gt;.&lt;font style="BACKGROUND-COLOR: #ffff00"&gt;IPAddressDequeued&lt;/font&gt;, &lt;span class=kwrd&gt;null&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;    }&lt;/pre&gt;
&lt;/div&gt;
&lt;style type=text/css&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;p&gt;
The &lt;em&gt;IPAddressResolved&lt;/em&gt; method just deals with the mechanics of printing out
the result of the lookup and then schedules another &lt;em&gt;BeginDequeue&lt;/em&gt; call to
start the next iteration. 
&lt;/p&gt;
&lt;p&gt;
Summary: The enabler for and the core piece of the implementation of this scenario
is &lt;em&gt;InputQueue&amp;lt;T&amp;gt;&lt;/em&gt; – the dequeue-callback enables implementing throttling
effectively and the dispatch logic provides an efficient way to leverage threads in
applications that leverage asynchronous programming patterns, especially in I/O driven
situations as illustrated here.
&lt;/p&gt;
&lt;p&gt;
And last but not least – here’s teh codez; project file is for VS2010, throw the files
into a new console app for VS2008 and mark the project to allow unsafe code (for the
I/O completion thread pool code).
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://vasters.com/clemensv/content/binary/UsingInputQueue.zip"&gt;UsingInputQueue.zip
(13.85 KB)&lt;/a&gt;&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
or if you'd rather have a version of InputQueue that is using the regular thread pool, &lt;a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=35ec8682-d5fd-4bc3-a51a-d8ad115a8792&amp;amp;displaylang=en"&gt;download
the WCF samples&lt;/a&gt;&amp;nbsp;and look for InputQueue.cs.
&lt;/p&gt;
&lt;p&gt;
[The sample code posted here is subject to the Windows SDK sample code license]
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=3d2486d4-2bfa-446c-886b-bf336f92c861" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,3d2486d4-2bfa-446c-886b-bf336f92c861.aspx</comments>
      <category>Architecture</category>
      <category>Technology/CLR</category>
      <category>Technology/WCF</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=57b03894-e197-4512-b9ea-648105890103</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,57b03894-e197-4512-b9ea-648105890103.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,57b03894-e197-4512-b9ea-648105890103.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=57b03894-e197-4512-b9ea-648105890103</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I was sad when "Indigo" and "Avalon" went away. It'd be great if we'd have
a pool of cool legal-approved code-names for which we own the trademark rights and
which we could stick to. Think Delphi or Safari. "Indigo" was cool insofar as
it was very handy to refer to the technology set, but was removed far enough
from the specifics that it doesn't create a sharply defined, product-like island
within the larger managed-code landscape or has legacy connotations like "ADO.NET".
 Also, my talks these days could be 10 minutes shorter if I could refer to Indigo
instead of "Windows Communications Foundation". Likewise, my job title wouldn't have
to have a line wrap on the business card of I ever spelled it out in full.
</p>
        <p>
However, when I learned about the WinFX name going away (several weeks before the
public announcement) and the new "Vista Wave" technologies (WPF/WF/WCF/WCS) being rolled
up under the <a href="http://msdn.microsoft.com/winfx/">.NET Framework</a> brand,
I was quite happy. Ever since it became clear in 2004 that the grand plan to put
a complete, covers-all-and-everything managed API on top (and on quite a
bit of the bottom) of everything Windows would have to wait until siginificantly after
Vista and that therefore the Win16&gt;Win32&gt;WinFX continuity would not
tell the true story, that name made only limited sense to stick to. The .NET Framework
is the #1 choice for business applications and a well established brand. People refer
to themselves as being "dotnet" developers. But even though the .NET Framework covers
a lot of ground and "Indigo", "Avalon", "InfoCard", and "Workflow" are overwhelmingly
(or exclusively) managed-code based, there are still quite a few things in Windows
Vista that still require using P/Invoke or COM/Interop from managed code or unmanaged
code outright. That's not a problem. Something has to manage the managed code
and there's no urgent need to rewrite entire subsystems to managed code if you
only want to add or revise features. 
</p>
        <p>
So now all the new stuff is now part of the .NET Framework. That is a good, good,
good change. This says what it all is. 
</p>
        <p>
Admittedly confusing is the "3.0" bit. What we'll ship is a Framework 3.0 that rides
on top of the 2.0 CLR and includes the 2.0 versions of the Base-Class Library, Windows
Forms, and ASP.NET. It doesn't include the formerly-announced-as-to-be-part-of-3.0
technologies like VB9 (there you have the version number consistency flying out
the window outright), C# 3.0, and LINQ. Personally, I think that it might be
a tiny bit less confusing if the Framework had a version-number neutral name such
as ".NET Framework 2006" which would allow doing what we do now with less potential
for confusion, but only a tiny bit. Certainly not enough to stage a war
over "2006" vs. "3.0".
</p>
        <p>
It's a matter of project management reality and also one of platform predictability
that the ASP.NET, or Windows Forms teams do not and should not ship a full
major-version revision of their bits every year. They shipped Whidbey (2.0) in late
2005 and hence it's healthy for them to have boarded the scheduled-to-arrive-in-2007
boat heading to Orcas. We (the "WinFX" teams) subscribed to the Vista ship docking later
this year and we bring great innovation which will be preinstalled on every copy of
it. LINQ as well as VB9 and C# incorporating it on a language-level are
very obviously Visual Studio bound and hence they are on the Orcas ferry as well.
The .NET Framework is a steadily growing development platform that spans technologies
from the Developer Division, Connected Systems, Windows Server, Windows Client, SQL
Server, and other groups, and my gut feeling is that it will become the norm that
it will be extended off-cycle from the Developer Division's Visual Studio and
CLR releases. Whenever a big ship docks in the port, may it be Office, SQL, BizTalk,
Windows Server, or Windows Client, and as more and more of the still-unmanaged Win32/Win64
surface area gets wrapped, augmented or replaced by managed-code APIs over time and
entirely new things are added, there might be bits that fit into and update the
Framework.  
</p>
        <p>
So one sane way to think about the .NET Framework version number is that it merely
labels the overall package and not the individual assemblies and components included
within it. Up to 2.0 everything was pretty synchronized, but given the ever-increasing
scale of the thing, it's good to think of that being a lucky (even if intended) coindicence
of scheduling. This surely <a href="http://en.wikipedia.org/wiki/Microsoft_BackOffice">isn't
the first time</a> that packages were versioned independently of their components.
There was and is no reason for the ASP.NET team to gratuitously recompile their existing
bits with a new version number just to have the GAC look pretty and to create the
illusion that everything is new - and to break Visual Studio compatibility in the
process.
</p>
        <p>
Of course, once we cover 100% of the Win32 surface area, we can rename it all into
WinFX again ;-)  (just kidding)
</p>
        <p>
[All the usual "personal opinion" disclaimers apply to this post]
</p>
        <p>
          <font size="1">
            <em>Update:</em> Removed reference to "Win64".</font>
        </p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=57b03894-e197-4512-b9ea-648105890103" />
      </body>
      <title>Code-Name WinFX vs .NET Framework 3.0</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,57b03894-e197-4512-b9ea-648105890103.aspx</guid>
      <link>http://vasters.com/clemensv/2006/06/18/CodeName+WinFX+Vs+NET+Framework+30.aspx</link>
      <pubDate>Sun, 18 Jun 2006 12:39:48 GMT</pubDate>
      <description>&lt;p&gt;
I was sad when "Indigo" and "Avalon" went away. It'd be great&amp;nbsp;if we'd&amp;nbsp;have
a pool of cool legal-approved code-names for which we own the trademark rights and
which we could stick to.&amp;nbsp;Think Delphi or Safari. "Indigo" was cool insofar as
it was very handy to refer to the technology set, but&amp;nbsp;was removed&amp;nbsp;far&amp;nbsp;enough
from the specifics that it doesn't&amp;nbsp;create a sharply defined, product-like island
within the larger managed-code landscape or has legacy connotations&amp;nbsp;like "ADO.NET".
&amp;nbsp;Also, my talks these days could be 10 minutes shorter if I could refer to Indigo
instead of "Windows Communications Foundation". Likewise, my job title wouldn't have
to&amp;nbsp;have a line wrap on the business card of I ever spelled it out in full.
&lt;/p&gt;
&lt;p&gt;
However, when I learned about the WinFX name going away (several weeks before the
public announcement) and the new "Vista Wave" technologies (WPF/WF/WCF/WCS) being&amp;nbsp;rolled
up&amp;nbsp;under the&amp;nbsp;&lt;a href="http://msdn.microsoft.com/winfx/"&gt;.NET Framework&lt;/a&gt;&amp;nbsp;brand,
I was&amp;nbsp;quite happy. Ever since it became clear in 2004 that the grand plan to&amp;nbsp;put
a complete,&amp;nbsp;covers-all-and-everything&amp;nbsp;managed API on top (and on quite a
bit of the bottom) of everything Windows would have to wait until siginificantly after
Vista and that&amp;nbsp;therefore&amp;nbsp;the Win16&amp;gt;Win32&amp;gt;WinFX continuity would not
tell the true story, that name made only limited sense to stick to. The .NET Framework
is the #1 choice for business applications and a well established brand. People refer
to themselves as being "dotnet" developers. But even though the .NET Framework covers
a lot of ground and "Indigo", "Avalon", "InfoCard", and "Workflow" are&amp;nbsp;overwhelmingly
(or exclusively) managed-code based, there are still quite a few things in Windows
Vista that still require using P/Invoke or COM/Interop from managed code or unmanaged
code outright. That's not a problem.&amp;nbsp;Something has to manage the managed code
and there's no urgent need to rewrite entire subsystems to managed code if&amp;nbsp;you
only want to add or revise features.&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
So now all the new stuff is now part of the .NET Framework. That is a good, good,
good&amp;nbsp;change. This says what it all is. 
&lt;/p&gt;
&lt;p&gt;
Admittedly confusing is the "3.0" bit. What we'll ship is a Framework 3.0 that rides
on top of the 2.0 CLR and includes the 2.0 versions of the Base-Class Library, Windows
Forms,&amp;nbsp;and ASP.NET. It doesn't include the formerly-announced-as-to-be-part-of-3.0
technologies like VB9 (there&amp;nbsp;you have the version number consistency flying out
the window outright), C# 3.0, and&amp;nbsp;LINQ. Personally, I think&amp;nbsp;that it might&amp;nbsp;be
a tiny bit less confusing if the Framework had a version-number neutral name such
as ".NET Framework 2006" which would allow&amp;nbsp;doing what we do now with less potential
for confusion, but only a tiny bit.&amp;nbsp;Certainly not enough to&amp;nbsp;stage a war
over "2006" vs. "3.0".
&lt;/p&gt;
&lt;p&gt;
It's a matter of project management&amp;nbsp;reality and also one of platform predictability
that the ASP.NET, or Windows Forms&amp;nbsp;teams&amp;nbsp;do not and should not ship a full
major-version revision of their bits every year. They shipped Whidbey (2.0) in late
2005 and hence&amp;nbsp;it's healthy for them&amp;nbsp;to&amp;nbsp;have boarded the scheduled-to-arrive-in-2007
boat heading to Orcas. We (the "WinFX" teams) subscribed to the Vista ship&amp;nbsp;docking&amp;nbsp;later
this year and we bring great innovation which will be preinstalled on every copy of
it. LINQ&amp;nbsp;as well as&amp;nbsp;VB9 and C# incorporating it on a language-level are
very obviously Visual Studio bound and hence they are on the Orcas ferry as well.
The .NET Framework is a steadily growing development platform that spans technologies
from the Developer Division, Connected Systems, Windows Server, Windows Client, SQL
Server, and other groups, and my gut feeling is that it will become the norm that
it will be extended off-cycle from the Developer Division's&amp;nbsp;Visual Studio and
CLR releases. Whenever a big ship docks in the port, may it be Office, SQL, BizTalk,
Windows Server, or Windows Client, and as more and more of the still-unmanaged Win32/Win64
surface area gets wrapped, augmented or replaced by managed-code APIs over time and
entirely new things are added, there might be bits that&amp;nbsp;fit into and update the
Framework. &amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
So one sane way to think about the .NET Framework version number is that&amp;nbsp;it merely
labels the overall package and not the individual assemblies and components included
within it. Up to 2.0&amp;nbsp;everything was pretty synchronized, but&amp;nbsp;given the ever-increasing
scale of the thing, it's good to think of that being a lucky (even if intended) coindicence
of scheduling. This surely &lt;a href="http://en.wikipedia.org/wiki/Microsoft_BackOffice"&gt;isn't
the first time&lt;/a&gt; that&amp;nbsp;packages were versioned independently of their components.
There was and is no reason for the ASP.NET team to gratuitously recompile their existing
bits with a new version number just to have the GAC look pretty and to create the
illusion that everything is new - and to break Visual Studio compatibility in the
process.
&lt;/p&gt;
&lt;p&gt;
Of course, once we cover 100% of the Win32 surface area, we can rename it all into
WinFX again ;-)&amp;nbsp; (just kidding)
&lt;/p&gt;
&lt;p&gt;
[All the usual&amp;nbsp;"personal opinion" disclaimers apply to this post]
&lt;/p&gt;
&lt;p&gt;
&lt;font size=1&gt;&lt;em&gt;Update:&lt;/em&gt; Removed reference to "Win64".&lt;/font&gt; 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=57b03894-e197-4512-b9ea-648105890103" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,57b03894-e197-4512-b9ea-648105890103.aspx</comments>
      <category>IT Strategy</category>
      <category>Technology</category>
      <category>Technology/ASP.NET</category>
      <category>Technology/Avalon</category>
      <category>Technology/CLR</category>
      <category>Technology/Indigo</category>
      <category>Technology/Longhorn</category>
      <category>Technology/WCF</category>
      <category>Technology/Windows</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=7dd9d6d9-e43f-4d83-a86e-9c37d5f7b4cc</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,7dd9d6d9-e43f-4d83-a86e-9c37d5f7b4cc.aspx</pingback:target>
      <dc:creator />
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,7dd9d6d9-e43f-4d83-a86e-9c37d5f7b4cc.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=7dd9d6d9-e43f-4d83-a86e-9c37d5f7b4cc</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <div class="Section1">
          <p>
I recently needed a TCP port-forwarder that sits on a socket connection and monitors
it. My concrete use-case is that I need to front the backend-server of my TV application
with such a port forwarder in order to create live-TV streaming sessions as soon as
a client requests them and also tears them down shortly after the client disconnects
so that the session doesn’t need to time out and blocks the tuner until then.
The backend also requires that I do a periodical “keep-alive” ping every
30-40 seconds, which isn’t a very practical requirement for some of my client
scenarios. Therefore, I needed, generally speaking, something that would sit between
the client and the backend server, monitors the data stream and would let me run some
code (set up the live session and start the keep-alive timer) when I get a new client
connection and just before I connect through to the target and which would let me
run some code (shut down the session and stop the keep-alive) as soon as the connection
is torn down. 
</p>
          <p>
Since, I didn’t find one (or was too blind or too lazy, you know how that goes),
I wrote one. It’s a fully asynchronous <i>TcpListener/TcpClient</i> based implementation,
it’s fast and stable enough for my purposes and it might or might not be for
yours, it has a bit of tolerance for targets that don’t accept a connection
on the first try, and you can hook up events to “before target connect”
and “after target disconnect”. Since all the bytes fly by, you can instrument
the thing further or monitor the stream as you like.  
</p>
          <p>
The code is pretty straightforward, even though the asynchronous calls/callbacks admittedly
make the execution paths in the implementation a bit challenging to follow, and should
not require much further explanation. You construct an instance of <i>TcpPortForwader </i>passing
the local port and the target port and host to forward to, call <i>Start() </i>and
the listener starts listening. <i>Stop()</i> stops the listener. You can call <i>Start()</i> from
any thread; the listener will implicitly use thread-pool threads to run on its own.
Hook up the events and they are being raised. Simple enough. Download below.
</p>
        </div>
        <p>
Download: <a href="http://staff.newtelligence.net/clemensv/content/binary/TcpPortForwarder.zip">TcpPortForwarder.zip</a><br /></p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=7dd9d6d9-e43f-4d83-a86e-9c37d5f7b4cc" />
      </body>
      <title>Managed TCP port-forwarder</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,7dd9d6d9-e43f-4d83-a86e-9c37d5f7b4cc.aspx</guid>
      <link>http://vasters.com/clemensv/2006/01/02/Managed+TCP+Portforwarder.aspx</link>
      <pubDate>Mon, 02 Jan 2006 11:08:46 GMT</pubDate>
      <description>

&lt;div class=Section1&gt;
&lt;p&gt;
I recently needed a TCP port-forwarder that sits on a socket connection and monitors
it. My concrete use-case is that I need to front the backend-server of my TV application
with such a port forwarder in order to create live-TV streaming sessions as soon as
a client requests them and also tears them down shortly after the client disconnects
so that the session doesn&amp;#8217;t need to time out and blocks the tuner until then.
The backend also requires that I do a periodical &amp;#8220;keep-alive&amp;#8221; ping every
30-40 seconds, which isn&amp;#8217;t a very practical requirement for some of my client
scenarios. Therefore, I needed, generally speaking, something that would sit between
the client and the backend server, monitors the data stream and would let me run some
code (set up the live session and start the keep-alive timer) when I get a new client
connection and just before I connect through to the target and which would let me
run some code (shut down the session and stop the keep-alive) as soon as the connection
is torn down. 
&lt;/p&gt;
&lt;p&gt;
Since, I didn&amp;#8217;t find one (or was too blind or too lazy, you know how that goes),
I wrote one. It&amp;#8217;s a fully asynchronous &lt;i&gt;TcpListener/TcpClient&lt;/i&gt; based implementation,
it&amp;#8217;s fast and stable enough for my purposes and it might or might not be for
yours, it has a bit of tolerance for targets that don&amp;#8217;t accept a connection
on the first try, and you can hook up events to &amp;#8220;before target connect&amp;#8221;
and &amp;#8220;after target disconnect&amp;#8221;. Since all the bytes fly by, you can instrument
the thing further or monitor the stream as you like. &amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
The code is pretty straightforward, even though the asynchronous calls/callbacks admittedly
make the execution paths in the implementation a bit challenging to follow, and should
not require much further explanation. You construct an instance of &lt;i&gt;TcpPortForwader &lt;/i&gt;passing
the local port and the target port and host to forward to, call &lt;i&gt;Start() &lt;/i&gt;and
the listener starts listening. &lt;i&gt;Stop()&lt;/i&gt; stops the listener. You can call &lt;i&gt;Start()&lt;/i&gt; from
any thread; the listener will implicitly use thread-pool threads to run on its own.
Hook up the events and they are being raised. Simple enough. Download below.
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
Download: &lt;a href="http://staff.newtelligence.net/clemensv/content/binary/TcpPortForwarder.zip"&gt;TcpPortForwarder.zip&lt;/a&gt;
&lt;br&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=7dd9d6d9-e43f-4d83-a86e-9c37d5f7b4cc" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,7dd9d6d9-e43f-4d83-a86e-9c37d5f7b4cc.aspx</comments>
      <category>Technology/CLR</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=514bac78-5c4e-4c57-9c15-e7736c83aa1d</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,514bac78-5c4e-4c57-9c15-e7736c83aa1d.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,514bac78-5c4e-4c57-9c15-e7736c83aa1d.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=514bac78-5c4e-4c57-9c15-e7736c83aa1d</wfw:commentRss>
      <slash:comments>6</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I was a little off when I compared <a href="http://staff.newtelligence.net/clemensv/CommentView.aspx?guid=1214e26d-674e-4a5c-b716-eaa07d327705">my
problem here</a> to a tail call. <a href="http://www.eighty-twenty.net/blog/urn:www-eighty-twenty-net:1250.html">Gordon
Weakliem</a> corrected me with the term "continuation".
</p>
        <p>
The fact that the post got 28 comments shows that this seems to be an interesting
problem and, naming aside, it is indeed a tricky thing to implement in a
framework when the programming language you use (C# in my case) doesn't support the
construct. What's specifically tricky about the concrete case that I have
is that I don't know where I am yielding control to at the time when I make the
respective call. 
</p>
        <p>
I'll recap. Assume there is the following call
</p>
        <p>
          <font size="4">
            <font face="Courier New">
              <font size="2">CustomerService cs = <font color="#0000ff">new</font></font>
            </font>
            <font face="Courier New" size="2"> CustomerService();<br /></font>
            <font size="2">
              <font face="Courier New">cs.FindCustomer(customerId);</font>
            </font>
          </font>
        </p>
        <p>
          <em>FindCustomer </em>is a call that will not return any result as a return value.
Instead, the invoked service comes back into the caller's program at some
completely different place such this:
</p>
        <p>
          <font size="4">
            <font face="Courier New">
              <font size="2">[WebMethod]<br />
public<font color="#000000"></font><font color="#0000ff">void</font></font>
            </font>
            <font face="Courier New">
              <font size="2">
                <font color="#000000"> FindCustomerReply(Customer[]
result)<br /></font>{<br />
   ...<br /></font>
            </font>
            <font size="2">
              <font face="Courier New">}</font>
            </font>
          </font>
        </p>
        <p>
So what we have here is a "duplex" conversation. The result of an operation initiated
by an outbound message (call) is received, some time later, through an inbound
message (call), but not on the same thread and not on the same "object". You
could say that this is a callback, but that's not precisely what it is, because a
"callback" usually happens while the initiating call (as above <em>FindCustomer</em>)
has not yet returned back to its scope or at least while the initiating object (or
an object passed by some sort of reference) is still alive. Here, instead, processing
of the <em>FindCustomer</em> call may take a while and the initiating thread and the
initiating object may be long gone when the answer is ready.
</p>
        <p>
Now, the additional issue I have is that at the time when the <em>FindCustomer</em> call
is made, it is not known what "<em>FindCustomerReply</em>" message handler it
going to be processing the result and it is really not know what's happening next.
The decision about what happens next and which handler is chosen is dependent on several
factors, including the time that it takes to receive the result. If the <em>FindCustomer</em> is
called from a web-page and the service providing <em>FindCustomer</em> drops
a result at the caller's doorstep within 2-3 seconds [1], the <em>FindCustomerReply</em> handler can
go and hijack the initial call's thread (and HTTP context) and render a page
showing the result. If the reply takes longer, the web-page (the caller) may lose
its patience [2] and choose to continue by rendering a page that says "We are sending
the result to your email account." and the message handler with not throw HTML into
an HTTP response on an open socket, but rather render it to an email and send
it via SMTP and maybe even alert the user through his/her Instant Messenger when/if
the result arrives.
</p>
        <p>
          <font size="4">
            <font face="Courier New">
              <font size="2">[1] HTTP Request =&gt; </font>
            </font>
            <font size="2">
              <font face="Courier New">FindCustomer()
=?&gt; "<font color="#000000">FindCustomerReply" =&gt; yield to CustomerList.aspx
=&gt; HTTP Response<br /><font color="#003300">[2] HTTP Request =&gt; </font><font size="2"><font face="Courier New"><font color="#003300">FindCustomer()
=?&gt; </font><font color="#000000">Timeout!           
=&gt; yield to YouWillGetMail.aspx =&gt; HTTP Response<br />
                               T+n =?&gt;
"FindCustomerReply" =&gt; SMTP Mail<br />
                                                          
=&gt; IM Notification</font></font></font></font></font>
            </font>
          </font>
        </p>
        <p>
So, in case [1] I need to correlate the reply with the request and continue processing
on the original thread. In case [2], the original thread continues on a
"default path" without an available reply and the reply is processed on (possibly
two) independent threads and using two different notification channels.
</p>
        <p>
A slightly different angle. Consider a workflow application environment in a bank,
where users are assigned tasks and simply fetch the next thing from the to-do
list (by clicking a link in an HTML-rendered list). The reply that results from "<em>LookupAndDoNextTask</em>" is
a message that contains the job that the user is supposed to do.  
</p>
        <p>
          <font face="Courier New">[1] HTTP Request =&gt; LookupAndDoNextTask<font size="2">()
=?&gt; Job: "<font color="#000000">Call Customer" =&gt; yield to CallCustomer.aspx =&gt;
HTTP Response<br /></font></font></font>
          <font face="Courier New">[2] HTTP Request =&gt; LookupAndDoNextTask<font size="2">()
=?&gt; Job: "<font color="#000000">Review Credit Offer" =&gt; yield to ReviewCredit.aspx =&gt;
HTTP Response<br /><font color="#003300">[3] HTTP Request =&gt; LookupAndDoNextTask</font><font size="2"><font color="#003300">()
=?&gt; Job: "</font><font color="#000000">Approve Mortgage" =&gt; yield to ApproveMortgage.aspx =&gt;
HTTP Response<br /><font color="#003300">[4] HTTP Request =&gt; LookupAndDoNextTask</font><font size="2"><font color="#003300">()
=?&gt; No Job / Timeout</font><font color="#000000"> =&gt; yield to Solitaire.aspx =&gt;
HTTP Response</font></font></font></font></font></font></font>
        </p>
        <p>
In all of these cases, calls to "FindCustomer()" and "LookupAndDoTask()" that are
made from the code that deals with the incoming request will (at least in the theoretical
model) never return to their caller and the thread will continue to execute in a different
context that is "TBD" at the time of the call. By the time the call stack is
unwound and the initiating call (like FindCustomer) indeed returns, the request
is therefore fully processed and the caller may not perform any further
actions. 
</p>
        <p>
So the issue at hand is to make that fact clear in the programming model. In ASP.NET,
there is a single construct called "Server.Transfer()" for that sort of continuation,
but it's very specific to ASP.NET and requires that the caller knows where you want
to yield control to. In the case I have here, the caller knows that it is surrendering
the thread to some other handler, but it doesn't know to to whom, because this is
dynamically determined by the underlying frameworks. All that's visible and should
be visible in the code is a "normal" method call.
</p>
        <p>
          <font size="4">
            <font size="2">
              <font face="Courier New">cs.FindCustomer(customerId) </font>
              <font face="Verdana">might
therefore not be a good name, because it looks "too normal". And of course I
don't have the powers to invent a new statement for the C# language
like </font>
              <font face="Courier New">
                <strong>continue(</strong>cs.FindCustomer(customerId)<strong>)</strong></font>
              <font face="Verdana"> that
would result in a continuation that simply doesn't return to the call location. Since
I can't do that, there has to be a different way to flag it. Sure, I could put an
attribute on the method, but Intellisense wouldn't show that, would it? So it seems
the best way is to have a convention of prefixing the method name.</font>
            </font>
          </font>
        </p>
        <p>
There were a bunch of ideas in the comments for method-name prefixes. Here is a selection: 
</p>
        <ul>
          <li>
            <font face="Courier New">cs.InitiateFindCustomer(customerId)</font>
          </li>
          <li>
            <font face="Courier New">cs.YieldFindCustomer(customerId)</font>
          </li>
          <li>
            <font face="Courier New">cs.YieldToFindCustomer(customerId)</font>
          </li>
          <li>
            <font face="Courier New">cs.InjectFindCustomer(customerId)</font>
          </li>
          <li>
            <font face="Courier New">cs.PlaceRequestFindCustomer(customerId)</font>
          </li>
          <li>
            <font face="Courier New">cs.PostRequestFindCustomer(customerId)</font>
          </li>
        </ul>
        <p>
I've got most of the underlying correlation and dispatch infrastructure
sitting here, but finding a good programming model for that sort of behavior
is quite difficult. 
</p>
        <p>
          <em>[Of course, this post won't make it on Microsoft Watch, eWeek or The
Register]</em>
        </p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=514bac78-5c4e-4c57-9c15-e7736c83aa1d" />
      </body>
      <title>Naming and Continuations (continued)</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,514bac78-5c4e-4c57-9c15-e7736c83aa1d.aspx</guid>
      <link>http://vasters.com/clemensv/2004/07/21/Naming+And+Continuations+Continued.aspx</link>
      <pubDate>Wed, 21 Jul 2004 08:24:16 GMT</pubDate>
      <description>&lt;p&gt;
I&amp;nbsp;was a little off&amp;nbsp;when I&amp;nbsp;compared&amp;nbsp;&lt;a href="http://staff.newtelligence.net/clemensv/CommentView.aspx?guid=1214e26d-674e-4a5c-b716-eaa07d327705"&gt;my
problem here&lt;/a&gt; to a tail call. &lt;a href="http://www.eighty-twenty.net/blog/urn:www-eighty-twenty-net:1250.html"&gt;Gordon
Weakliem&lt;/a&gt; corrected me with the term "continuation".
&lt;/p&gt;
&lt;p&gt;
The fact that the post got 28 comments shows that this seems to be an interesting
problem and, naming aside, it&amp;nbsp;is indeed a tricky thing to&amp;nbsp;implement in a
framework when the programming language you use (C# in my case) doesn't support the
construct.&amp;nbsp;What's specifically tricky about the&amp;nbsp;concrete case that I have
is that I don't&amp;nbsp;know where I am yielding control to at the time when I make the
respective call. 
&lt;/p&gt;
&lt;p&gt;
I'll recap. Assume there is the following call
&lt;/p&gt;
&lt;p&gt;
&lt;font size=4&gt;&lt;font face="Courier New"&gt;&lt;font size=2&gt;CustomerService&amp;nbsp;cs = &lt;font color=#0000ff&gt;new&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New" size=2&gt; CustomerService();&lt;br&gt;
&lt;/font&gt;&lt;font size=2&gt;&lt;font face="Courier New"&gt;cs.FindCustomer(customerId);&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;FindCustomer &lt;/em&gt;is a&amp;nbsp;call that will not return any result as a return value.
Instead,&amp;nbsp;the invoked service&amp;nbsp;comes back into the caller's program at some
completely different place such this:
&lt;/p&gt;
&lt;p&gt;
&lt;font size=4&gt;&lt;font face="Courier New"&gt;&lt;font size=2&gt;[WebMethod]&lt;br&gt;
public&lt;font color=#000000&gt; &lt;/font&gt;&lt;font color=#0000ff&gt;void&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font size=2&gt;&lt;font color=#000000&gt; FindCustomerReply(Customer[]
result)&lt;br&gt;
&lt;/font&gt;{&lt;br&gt;
&amp;nbsp;&amp;nbsp; ...&lt;br&gt;
&lt;/font&gt;&lt;/font&gt;&lt;font size=2&gt;&lt;font face="Courier New"&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
So what we have here is a "duplex" conversation. The result of an operation initiated
by an outbound&amp;nbsp;message (call) is received, some time later,&amp;nbsp;through an inbound
message&amp;nbsp;(call), but not on the same thread and not on the same "object".&amp;nbsp;You
could say that this is a callback, but that's not precisely what it is, because&amp;nbsp;a
"callback" usually happens&amp;nbsp;while the&amp;nbsp;initiating call (as above &lt;em&gt;FindCustomer&lt;/em&gt;)
has not yet returned back to its scope or at least while the initiating object (or
an object passed by some sort of reference) is still alive.&amp;nbsp;Here, instead,&amp;nbsp;processing
of the &lt;em&gt;FindCustomer&lt;/em&gt; call may take a while and the initiating thread and the
initiating object may be long gone when the answer is ready.
&lt;/p&gt;
&lt;p&gt;
Now, the additional issue I have is that at the time when the &lt;em&gt;FindCustomer&lt;/em&gt; call
is made, it is not&amp;nbsp;known what "&lt;em&gt;FindCustomerReply&lt;/em&gt;" message handler it
going to be processing the result and it is really not know what's happening next.
The decision about what happens next and which handler is chosen is dependent on several
factors, including the time that it takes to receive the result. If the &lt;em&gt;FindCustomer&lt;/em&gt; is
called from a web-page and the service providing &lt;em&gt;FindCustomer&lt;/em&gt;&amp;nbsp;drops
a result at the caller's doorstep within 2-3 seconds [1], the &lt;em&gt;FindCustomerReply&lt;/em&gt; handler&amp;nbsp;can
go and&amp;nbsp;hijack the initial call's thread (and HTTP context) and render a page
showing the result. If the reply takes longer, the web-page (the caller) may lose
its patience [2] and choose to continue by rendering a page that says "We are sending
the result to your email account." and the message handler with not throw HTML into
an&amp;nbsp;HTTP response on an open socket, but rather render it to an email and send
it via SMTP and maybe even alert the user through his/her Instant Messenger&amp;nbsp;when/if
the result arrives.
&lt;/p&gt;
&lt;p&gt;
&lt;font size=4&gt;&lt;font face="Courier New"&gt;&lt;font size=2&gt;[1] HTTP Request =&amp;gt; &lt;/font&gt;&lt;/font&gt;&lt;font size=2&gt;&lt;font face="Courier New"&gt;FindCustomer()
=?&amp;gt; "&lt;font color=#000000&gt;FindCustomerReply" =&amp;gt; yield to CustomerList.aspx =&amp;gt;
HTTP Response&lt;br&gt;
&lt;font color=#003300&gt;[2] HTTP Request =&amp;gt; &lt;/font&gt;&lt;font size=2&gt;&lt;font face="Courier New"&gt;&lt;font color=#003300&gt;FindCustomer()
=?&amp;gt; &lt;/font&gt;&lt;font color=#000000&gt;Timeout!&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
=&amp;gt; yield to YouWillGetMail.aspx =&amp;gt; HTTP Response&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;T+n&amp;nbsp;=?&amp;gt;
"FindCustomerReply" =&amp;gt; SMTP Mail&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
=&amp;gt; IM Notification&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
So, in case [1] I need to correlate the reply with the request and&amp;nbsp;continue processing
on the original thread. In&amp;nbsp;case [2], the original thread continues&amp;nbsp;on&amp;nbsp;a
"default path"&amp;nbsp;without an available reply and the reply is processed on (possibly
two) independent threads and using two different notification channels.
&lt;/p&gt;
&lt;p&gt;
A slightly different angle. Consider a workflow application environment in a bank,
where users are assigned tasks and simply fetch the next thing&amp;nbsp;from the to-do
list (by clicking a link in an HTML-rendered list). The reply that results from "&lt;em&gt;LookupAndDoNextTask&lt;/em&gt;"&amp;nbsp;is
a message that contains the job that the user is supposed to do. &amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;[1] HTTP Request =&amp;gt; LookupAndDoNextTask&lt;font size=2&gt;()
=?&amp;gt; Job: "&lt;font color=#000000&gt;Call Customer" =&amp;gt; yield to CallCustomer.aspx&amp;nbsp;=&amp;gt;
HTTP Response&lt;br&gt;
&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;[2] HTTP Request =&amp;gt; LookupAndDoNextTask&lt;font size=2&gt;()
=?&amp;gt; Job: "&lt;font color=#000000&gt;Review Credit Offer" =&amp;gt; yield to ReviewCredit.aspx&amp;nbsp;=&amp;gt;
HTTP Response&lt;br&gt;
&lt;font color=#003300&gt;[3] HTTP Request =&amp;gt; LookupAndDoNextTask&lt;/font&gt;&lt;font size=2&gt;&lt;font color=#003300&gt;()
=?&amp;gt; Job: "&lt;/font&gt;&lt;font color=#000000&gt;Approve Mortgage" =&amp;gt; yield to ApproveMortgage.aspx&amp;nbsp;=&amp;gt;
HTTP Response&lt;br&gt;
&lt;font color=#003300&gt;[4] HTTP Request =&amp;gt; LookupAndDoNextTask&lt;/font&gt;&lt;font size=2&gt;&lt;font color=#003300&gt;()
=?&amp;gt;&amp;nbsp;No Job / Timeout&lt;/font&gt;&lt;font color=#000000&gt;&amp;nbsp;=&amp;gt; yield to Solitaire.aspx&amp;nbsp;=&amp;gt;
HTTP Response&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
In all of these cases, calls to "FindCustomer()" and "LookupAndDoTask()" that are
made from the code that deals with the incoming request will (at least in the theoretical
model) never return to their caller and the thread will continue to execute in a different
context that is&amp;nbsp;"TBD" at the time of the call. By the time the call stack is
unwound and the&amp;nbsp;initiating call (like FindCustomer) indeed returns, the request
is therefore fully processed and the caller&amp;nbsp;may not&amp;nbsp;perform any further
actions.&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
So the issue at hand is to make that fact clear in the programming model. In ASP.NET,
there is a single construct called "Server.Transfer()" for that sort of continuation,
but it's very specific to ASP.NET and requires that the caller knows where you want
to yield control to.&amp;nbsp;In the case I have here, the caller knows that it is surrendering
the thread to some other handler, but it doesn't know to to whom, because this is
dynamically determined by the underlying frameworks. All that's visible and should
be visible in the code is a "normal" method call.
&lt;/p&gt;
&lt;p&gt;
&lt;font size=4&gt;&lt;font size=2&gt;&lt;font face="Courier New"&gt;cs.FindCustomer(customerId)&amp;nbsp;&lt;/font&gt;&lt;font face=Verdana&gt;might
therefore not be a good name, because&amp;nbsp;it looks "too normal". And of course I
don't have the powers to&amp;nbsp;invent a new&amp;nbsp;statement&amp;nbsp;for the C# language
like&amp;nbsp;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;strong&gt;continue(&lt;/strong&gt;cs.FindCustomer(customerId)&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;font face=Verdana&gt;&amp;nbsp;that
would result in a continuation that simply doesn't return to the call location. Since
I can't do that, there has to be a different way to flag it. Sure, I could put an
attribute on the method, but Intellisense wouldn't show that, would it? So it seems
the best way is to have a convention of prefixing the method name.&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
There were a bunch of ideas in the comments for method-name prefixes. Here is a selection: 
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;font face="Courier New"&gt;cs.InitiateFindCustomer(customerId)&lt;/font&gt; 
&lt;li&gt;
&lt;font face="Courier New"&gt;cs.YieldFindCustomer(customerId)&lt;/font&gt; 
&lt;li&gt;
&lt;font face="Courier New"&gt;cs.YieldToFindCustomer(customerId)&lt;/font&gt; 
&lt;li&gt;
&lt;font face="Courier New"&gt;cs.InjectFindCustomer(customerId)&lt;/font&gt; 
&lt;li&gt;
&lt;font face="Courier New"&gt;cs.PlaceRequestFindCustomer(customerId)&lt;/font&gt; 
&lt;li&gt;
&lt;font face="Courier New"&gt;cs.PostRequestFindCustomer(customerId)&lt;/font&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
I've got most of the&amp;nbsp;underlying&amp;nbsp;correlation and dispatch infrastructure
sitting here, but finding a good&amp;nbsp;programming model for that sort of behavior
is quite difficult. 
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;[Of course, this post won't make it on Microsoft Watch,&amp;nbsp;eWeek&amp;nbsp;or The
Register]&lt;/em&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=514bac78-5c4e-4c57-9c15-e7736c83aa1d" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,514bac78-5c4e-4c57-9c15-e7736c83aa1d.aspx</comments>
      <category>Architecture</category>
      <category>Architecture/SOA</category>
      <category>Technology</category>
      <category>Technology/ASP.NET</category>
      <category>Technology/CLR</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=7624014a-c9d9-4924-bad2-fdcf054c5185</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,7624014a-c9d9-4924-bad2-fdcf054c5185.aspx</pingback:target>
      <dc:creator />
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,7624014a-c9d9-4924-bad2-fdcf054c5185.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=7624014a-c9d9-4924-bad2-fdcf054c5185</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I didn't spend much time for anything except writing, coding, travel, speaking and
being at geek parties in the past weeks. Hence, I am sure I am the last one to notice,
but I find it absolutely revolutionary that the Microsoft Visual C++ 2003 command
line compiler (Microsoft C/C++ Version 13.1) is <a href="http://msdn.microsoft.com/visualc/vctoolkit2003/">now
a freebie</a>. 
</p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=7624014a-c9d9-4924-bad2-fdcf054c5185" />
      </body>
      <title>Scusi? Visual C++ Compiler for free? Woo!</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,7624014a-c9d9-4924-bad2-fdcf054c5185.aspx</guid>
      <link>http://vasters.com/clemensv/2004/05/16/Scusi+Visual+C+Compiler+For+Free+Woo.aspx</link>
      <pubDate>Sun, 16 May 2004 07:46:49 GMT</pubDate>
      <description>&lt;p&gt;
I didn't spend much time for anything except writing, coding, travel, speaking and
being at geek parties in the past weeks. Hence, I am sure I am the last one to notice,
but I find it absolutely revolutionary that the&amp;nbsp;Microsoft Visual C++ 2003 command
line compiler (Microsoft C/C++ Version 13.1) is &lt;a href="http://msdn.microsoft.com/visualc/vctoolkit2003/"&gt;now
a freebie&lt;/a&gt;. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=7624014a-c9d9-4924-bad2-fdcf054c5185" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,7624014a-c9d9-4924-bad2-fdcf054c5185.aspx</comments>
      <category>Technology</category>
      <category>Technology/CLR</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=ca3668cd-acf8-4bbb-81ff-b26bfde327d4</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,ca3668cd-acf8-4bbb-81ff-b26bfde327d4.aspx</pingback:target>
      <dc:creator />
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,ca3668cd-acf8-4bbb-81ff-b26bfde327d4.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=ca3668cd-acf8-4bbb-81ff-b26bfde327d4</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
We just had a short discussion here at the office on the goodness and badness of using
Reflection to cheat around private and protected and cases where it does and doesn't
work (it's of course a System.Security.Permissions.ReflectionPermission
thing). The discussion brought back memories of that old C/C++ hack that
I've been using for almost any application back in my Borland C++ and
OWL days:
</p>
        <p>
#define private public<br />
#define protected public<br />
#include &lt;owl.h&gt;
</p>
        <p>
 
</p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=ca3668cd-acf8-4bbb-81ff-b26bfde327d4" />
      </body>
      <title>public, protected, private</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,ca3668cd-acf8-4bbb-81ff-b26bfde327d4.aspx</guid>
      <link>http://vasters.com/clemensv/2003/10/01/public+Protected+Private.aspx</link>
      <pubDate>Wed, 01 Oct 2003 13:43:34 GMT</pubDate>
      <description>&lt;p&gt;
We just had a short discussion here at the office on the goodness and badness of using
Reflection to cheat around private and protected and cases where it does and doesn't
work (it's&amp;nbsp;of course&amp;nbsp;a System.Security.Permissions.ReflectionPermission
thing). The discussion&amp;nbsp;brought back memories of that old C/C++&amp;nbsp;hack that
I've been using for&amp;nbsp;almost any application&amp;nbsp;back in&amp;nbsp;my Borland C++ and
OWL days:
&lt;/p&gt;
&lt;p&gt;
#define private public&lt;br&gt;
#define protected public&lt;br&gt;
#include &amp;lt;owl.h&amp;gt;
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=ca3668cd-acf8-4bbb-81ff-b26bfde327d4" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,ca3668cd-acf8-4bbb-81ff-b26bfde327d4.aspx</comments>
      <category>Technology</category>
      <category>Technology/CLR</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=0615b3cc-0fbf-4cf5-9d49-ae95b50f7e8d</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,0615b3cc-0fbf-4cf5-9d49-ae95b50f7e8d.aspx</pingback:target>
      <dc:creator />
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,0615b3cc-0fbf-4cf5-9d49-ae95b50f7e8d.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=0615b3cc-0fbf-4cf5-9d49-ae95b50f7e8d</wfw:commentRss>
      <slash:comments>6</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <div class="Section1">
          <p>
            <img height="399" hspace="12" src="http://staff.newtelligence.net/clemensv/content/binary/image0011234.jpg" width="341" align="left" vspace="11" />A
long while back, <a href="http://radio.weblogs.com/0108971/2002/07/16.html#a13">I
wrote about</a> a hack to fix the dllhost.exe.config dilemma of Enterprise Services.
That hack no longer works due to changes in the Framework, but the good news is there
is an “official” and very easy solution for this now. Unfortunately there is no documentation
on this (or at least it’s not easy enough to find that I could locate it) and Google
only yields a few hints if you know exactly what you are looking for. So, index this,
Google!
</p>
          <p>
What I call the “config dilemma” of Enterprise Services is that because all out-of-process
ES applications are executed using the surrogate process provided by <i>%SystemRoot%\System32\dllhost.exe</i> and
the runtime is loaded into that process, the default application configuration file
is dllhost.exe.config, must reside just next to dllhost.exe (in System32) and is therefore
shared across all out-of-process Enterprise Services applications.
</p>
          <p>
That makes using the XML configuration infrastructure for Enterprise Services very
unattractive, to say the least.
</p>
          <p>
Now, with COM+ 1.5 (Windows Server 2003) and the .NET Framework 1.1, things did change
in a big way. 
</p>
          <p>
To use per-application application configuration files, all you have to do is to create
an (possibly otherwise empty) “application root directory” for your application in
which you place two files: An <b><i>application.manifest</i></b> file (that exact
name) and an <b><i>application.config</i></b> file. Once your application is registered
(lazy or using the <i>RegistrationHelper</i> class or through regsvcs.exe), you will
have to configure the application’s root directory in the catalog – that can be done
either programmatically using the <a href="http://msdn.microsoft.com/library/en-us/cossdk/htm/comadmincollections 2ram.asp?frame=true# cos applications applicationdirectory">catalog
admin API</a> (ApplicationDirectory property) or through the Component Services explorer
as shown above.
</p>
          <p>
The picture shows that the example that you can download using the link below is installed
at “c:\Development\ES\ConfigTest\ESTest” on my machine and has these two said files
sitting right there. 
</p>
          <p>
The <b><i>application.manifest</i></b> file content is embarrassingly simple
</p>
          <p class="MsoNormal">
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">&lt;?<span style="COLOR: maroon">xml</span><span style="COLOR: fuchsia"></span><span style="COLOR: red">version</span>="1.0"<span style="COLOR: fuchsia"></span><span style="COLOR: red">encoding</span>="UTF-8"<span style="COLOR: fuchsia"></span><span style="COLOR: red">standalone</span>="yes"?&gt;<br />
&lt;<span style="COLOR: maroon">assembly</span><span style="COLOR: fuchsia"></span><span style="COLOR: red">xmlns</span>="urn:schemas-microsoft-com:asm.v1"<span style="COLOR: fuchsia"></span><span style="COLOR: red">manifestVersion</span>="1.0"&gt;<br />
&lt;/<span style="COLOR: maroon">assembly</span>&gt;</span>
          </p>
          <p>
and the <b><i>application.config</i></b> isn’t complicated either:
</p>
          <p class="MsoNormal">
            <span style="FONT-SIZE: 8pt; COLOR: blue; FONT-FAMILY: 'Courier New'">&lt;?</span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">xml<span style="COLOR: fuchsia"></span><span style="COLOR: red">version</span><span style="COLOR: blue">="1.0"?&gt;<br />
&lt;</span>configuration<span style="COLOR: blue">&gt;<br /></span>  <span style="COLOR: blue">&lt;</span>appSettings<span style="COLOR: blue">&gt;<br /></span>     <span style="COLOR: blue">&lt;</span>add<span style="COLOR: fuchsia"></span><span style="COLOR: red">key</span><span style="COLOR: blue">="configBit"</span><span style="COLOR: fuchsia"></span><span style="COLOR: red">value</span><span style="COLOR: blue">="This
rocks!"/&gt;<br /></span>  <span style="COLOR: blue">&lt;/</span>appSettings<span style="COLOR: blue">&gt;<br />
&lt;/</span>configuration<span style="COLOR: blue">&gt;</span></span>
          </p>
          <p>
These two files, placed into the same directory and properly configured as shown in
the above picture, let this class
</p>
          <p class="MsoNormal">
            <span style="FONT-SIZE: 8pt; COLOR: blue; FONT-FAMILY: 'Courier New'">      
public</span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">
              <span style="COLOR: blue">class</span> SimpleComponent
: ServicedComponent<br />
       {<br />
        p<span style="COLOR: blue">ublic</span><span style="COLOR: blue">string</span> GetConfigBit()<br />
        {<br />
            <span style="COLOR: blue">return</span> ConfigurationSettings.AppSettings["configBit"];<br />
        }<br />
       }</span>
          </p>
          <p>
yield the expected result for GetConfigBit(): “This rocks!”
</p>
          <p>
 
</p>
          <p>
 
</p>
        </div>
        <p>
Download: <a href="http://staff.newtelligence.net/clemensv/content/binary/ESTest.zip">ESTest.zip</a><br /></p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=0615b3cc-0fbf-4cf5-9d49-ae95b50f7e8d" />
      </body>
      <title>dllhost.exe.config dilemma fixed, at last -- by Microsoft.</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,0615b3cc-0fbf-4cf5-9d49-ae95b50f7e8d.aspx</guid>
      <link>http://vasters.com/clemensv/2003/09/26/dllhostexeconfig+Dilemma+Fixed+At+Last+By+Microsoft.aspx</link>
      <pubDate>Fri, 26 Sep 2003 11:37:36 GMT</pubDate>
      <description>&lt;div class=Section1&gt;
&lt;p&gt;
&lt;img height=399 hspace=12 src="http://staff.newtelligence.net/clemensv/content/binary/image0011234.jpg" width=341 align=left vspace=11&gt;A
long while back, &lt;a href="http://radio.weblogs.com/0108971/2002/07/16.html#a13"&gt;I
wrote about&lt;/a&gt; a hack to fix the dllhost.exe.config dilemma of Enterprise Services.
That hack no longer works due to changes in the Framework, but the good news is there
is an “official” and very easy solution for this now. Unfortunately there is no documentation
on this (or at least it’s not easy enough to find that I could locate it) and Google
only yields a few hints if you know exactly what you are looking for. So, index this,
Google!
&lt;/p&gt;
&lt;p&gt;
What I call the “config dilemma” of Enterprise Services is that because all out-of-process
ES applications are executed using the surrogate process provided by &lt;i&gt;%SystemRoot%\System32\dllhost.exe&lt;/i&gt; and
the runtime is loaded into that process, the default application configuration file
is dllhost.exe.config, must reside just next to dllhost.exe (in System32) and is therefore
shared across all out-of-process Enterprise Services applications.
&lt;/p&gt;
&lt;p&gt;
That makes using the XML configuration infrastructure for Enterprise Services very
unattractive, to say the least.
&lt;/p&gt;
&lt;p&gt;
Now, with COM+ 1.5 (Windows Server 2003) and the .NET Framework 1.1, things did change
in a big way. 
&lt;/p&gt;
&lt;p&gt;
To use per-application application configuration files, all you have to do is to create
an (possibly otherwise empty) “application root directory” for your application in
which you place two files: An &lt;b&gt;&lt;i&gt;application.manifest&lt;/i&gt;&lt;/b&gt; file (that exact
name) and an &lt;b&gt;&lt;i&gt;application.config&lt;/i&gt;&lt;/b&gt; file. Once your application is registered
(lazy or using the &lt;i&gt;RegistrationHelper&lt;/i&gt; class or through regsvcs.exe), you will
have to configure the application’s root directory in the catalog – that can be done
either programmatically using the &lt;a href="http://msdn.microsoft.com/library/en-us/cossdk/htm/comadmincollections 2ram.asp?frame=true# cos applications applicationdirectory"&gt;catalog
admin API&lt;/a&gt; (ApplicationDirectory property) or through the Component Services explorer
as shown above.
&lt;/p&gt;
&lt;p&gt;
The picture shows that the example that you can download using the link below is installed
at “c:\Development\ES\ConfigTest\ESTest” on my machine and has these two said files
sitting right there. 
&lt;/p&gt;
&lt;p&gt;
The &lt;b&gt;&lt;i&gt;application.manifest&lt;/i&gt;&lt;/b&gt; file content is embarrassingly simple
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;lt;?&lt;span style="COLOR: maroon"&gt;xml&lt;/span&gt;&lt;span style="COLOR: fuchsia"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;version&lt;/span&gt;="1.0"&lt;span style="COLOR: fuchsia"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;encoding&lt;/span&gt;="UTF-8"&lt;span style="COLOR: fuchsia"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;standalone&lt;/span&gt;="yes"?&amp;gt;&lt;br&gt;
&amp;lt;&lt;span style="COLOR: maroon"&gt;assembly&lt;/span&gt;&lt;span style="COLOR: fuchsia"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;xmlns&lt;/span&gt;="urn:schemas-microsoft-com:asm.v1"&lt;span style="COLOR: fuchsia"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;manifestVersion&lt;/span&gt;="1.0"&amp;gt;&lt;br&gt;
&amp;lt;/&lt;span style="COLOR: maroon"&gt;assembly&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
and the &lt;b&gt;&lt;i&gt;application.config&lt;/i&gt;&lt;/b&gt; isn’t complicated either:
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;span style="FONT-SIZE: 8pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;xml&lt;span style="COLOR: fuchsia"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;version&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="1.0"?&amp;gt;&lt;br&gt;
&amp;lt;&lt;/span&gt;configuration&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;appSettings&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;add&lt;span style="COLOR: fuchsia"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;key&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="configBit"&lt;/span&gt;&lt;span style="COLOR: fuchsia"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;value&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="This
rocks!"/&amp;gt;&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;appSettings&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;br&gt;
&amp;lt;/&lt;/span&gt;configuration&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
These two files, placed into the same directory and properly configured as shown in
the above picture, let this class
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;span style="FONT-SIZE: 8pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
public&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt; &lt;span style="COLOR: blue"&gt;class&lt;/span&gt; SimpleComponent
: ServicedComponent&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;p&lt;span style="COLOR: blue"&gt;ublic&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; GetConfigBit()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; ConfigurationSettings.AppSettings["configBit"];&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
yield the expected result for GetConfigBit(): “This rocks!”
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
Download: &lt;a href="http://staff.newtelligence.net/clemensv/content/binary/ESTest.zip"&gt;ESTest.zip&lt;/a&gt;
&lt;br&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=0615b3cc-0fbf-4cf5-9d49-ae95b50f7e8d" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,0615b3cc-0fbf-4cf5-9d49-ae95b50f7e8d.aspx</comments>
      <category>Technology/CLR</category>
      <category>Technology/Enterprise Services</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=bfafde8c-94dc-4231-be0d-f0fbefc81e50</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,bfafde8c-94dc-4231-be0d-f0fbefc81e50.aspx</pingback:target>
      <dc:creator />
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,bfafde8c-94dc-4231-be0d-f0fbefc81e50.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=bfafde8c-94dc-4231-be0d-f0fbefc81e50</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Lots of PDC hype these days. Here's a piece an <a href="http://wesnerm.blogs.com/net_undocumented/2003/09/learn_about_ava.html">Avalon</a> by
Wesner Moise that's still leaving quite a bit in the fog. 
</p>
        <p>
My translation of what I am reading from the abstracts is: 
</p>
        <p>
Imagine Microsoft would <em>drop</em> the entire USER32 subsystem of Windows and <em>replace</em> it
with a brand-spanking-new windowing and I/O engine and a fully object-oriented, managed
API, finally doing the long-overdue overhaul and replacement of the foundation of
the Windows UI technologies that have, in essence, been with us since <a href="http://internet.ls-la.net/ms-evolution/windows-1.03/">Windows
1.0</a>.
</p>
        <p>
.... and create a WOW ("Windows on Windows") subsystem layer, not dissimilar to what
we saw in NT for Win16 apps, to support existing apps.
</p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=bfafde8c-94dc-4231-be0d-f0fbefc81e50" />
      </body>
      <title>PDC speculations: Avalon</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,bfafde8c-94dc-4231-be0d-f0fbefc81e50.aspx</guid>
      <link>http://vasters.com/clemensv/2003/09/26/PDC+Speculations+Avalon.aspx</link>
      <pubDate>Fri, 26 Sep 2003 05:59:39 GMT</pubDate>
      <description>&lt;p&gt;
Lots of PDC hype these days. Here's a piece an &lt;a href="http://wesnerm.blogs.com/net_undocumented/2003/09/learn_about_ava.html"&gt;Avalon&lt;/a&gt;&amp;nbsp;by
Wesner Moise that's still&amp;nbsp;leaving quite a&amp;nbsp;bit in the fog. 
&lt;/p&gt;
&lt;p&gt;
My translation of what I am reading from the abstracts is: 
&lt;/p&gt;
&lt;p&gt;
Imagine Microsoft would &lt;em&gt;drop&lt;/em&gt; the entire USER32 subsystem of Windows and &lt;em&gt;replace&lt;/em&gt; it
with a brand-spanking-new windowing and I/O engine and a fully object-oriented, managed
API, finally doing the long-overdue overhaul and replacement of the foundation of
the Windows UI technologies that have, in essence, been with us since &lt;a href="http://internet.ls-la.net/ms-evolution/windows-1.03/"&gt;Windows
1.0&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
.... and create a WOW ("Windows on Windows") subsystem layer, not dissimilar to what
we saw in NT for Win16 apps, to support existing apps.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=bfafde8c-94dc-4231-be0d-f0fbefc81e50" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,bfafde8c-94dc-4231-be0d-f0fbefc81e50.aspx</comments>
      <category>PDC 03</category>
      <category>Technology/CLR</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=d3fbcdef-3387-41c5-a645-df3f6615c1e4</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,d3fbcdef-3387-41c5-a645-df3f6615c1e4.aspx</pingback:target>
      <dc:creator />
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,d3fbcdef-3387-41c5-a645-df3f6615c1e4.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=d3fbcdef-3387-41c5-a645-df3f6615c1e4</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <div class="Section1">
          <p>
I am in a blogging mood today … Here are some thoughts around composite metadata.
Sorry for the bold title ;)
</p>
          <p style="TEXT-ALIGN: center" align="center">
* * *
</p>
          <p>
Whenever I am asked what I consider the most important innovation of the CLR, I don’t
hesitate to respond “extensible metadata”<span style="COLOR: navy"></span>com<span style="COLOR: navy">ing</span> in
the form of custom attributes. Everyone who has followed this blog for a while and
looked at some of the source code I published knows that I am seriously in love with
attributes. In fact, very few of the projects I write don’t include at least one class
derived from <i>Attribute</i> and once you use the <i>XmlSerializer</i>, Enterprise
Services or ASMX, there’s no way around using them.
</p>
          <p>
In my keynote on contracts and metadata at the Norwegian Visual Studio .NET 2003 launch
earlier this year, I used the sample that’s attached at the bottom of this article.
It illustrates how contracts can be enforced by both, schema validation and validation
of object graphs based on the same set of constraints. In schema, the constraints
are defined using metadata (restrictions) inside element or type definitions, and
in classes, the very same restrictions can be applied using custom attributes, given
you have a sufficient set of attributes and the respective validation logic. In both
cases, the data is run through a filter that’s driven by the metadata information.
If either filter is used at the inbound <i>and outbound</i> channels of a service,
contract enforcement is automatic and “contract trust” between services, as defined
in my <a href="http://staff.newtelligence.net/clemensv/PermaLink.aspx?guid=b379fb50-70b2-48b1-9d56-7cc5377022e5">previous
article</a>, can be achieved. So far, so good.
</p>
          <p>
In my example, the metadata instrumentation for a CLR type looks like this:
</p>
          <p class="MsoNormal">
            <span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'">      </span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">[System.Xml.Serialization.XmlTypeAttribute(<br />
           Namespace="urn:schemas-newtelligence-com:transactionsamples:customerdata:v1")]<br /></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">       <span style="COLOR: blue">public</span><span style="COLOR: blue">class</span> addressType<br /></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">      
{<br /></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">             
[Match(@"\p{L}[\p{L}\p{P}0-9\s]*"),MaxLength(80)]<br /></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">              <span style="COLOR: blue">public</span><span style="COLOR: blue">string</span> City;<br /></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">              <span style="COLOR: blue">public</span> countryNameType
Country;<br /></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">              <span style="COLOR: blue">public</span> countryCodeType
CountryCode;<br /></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">             
[MaxLength(10)]<br /></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">              <span style="COLOR: blue">public</span><span style="COLOR: blue">string</span> PostalCode;<br /></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">             
[MaxLength(160)]<br /></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">              <span style="COLOR: blue">public</span><span style="COLOR: blue">string</span> AddressLine;<br />
      }</span>
          </p>
          <p>
… while the corresponding schema is a bit better factored and looks like this:
</p>
          <p class="MsoNormal">
            <span style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Lucida Console'">    </span>
            <span style="FONT-SIZE: 8pt; COLOR: blue; FONT-FAMILY: 'Courier New'">&lt;</span>
            <span style="FONT-SIZE: 8pt; COLOR: maroon; FONT-FAMILY: 'Courier New'">xsd:simpleType</span>
            <span style="FONT-SIZE: 8pt; COLOR: fuchsia; FONT-FAMILY: 'Courier New'">
            </span>
            <span style="FONT-SIZE: 8pt; COLOR: red; FONT-FAMILY: 'Courier New'">name</span>
            <span style="FONT-SIZE: 8pt; COLOR: blue; FONT-FAMILY: 'Courier New'">="nameType"&gt;<br /></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">              <span style="COLOR: blue">&lt;</span><span style="COLOR: maroon">xsd:restriction</span><span style="COLOR: fuchsia"></span><span style="COLOR: red">base</span><span style="COLOR: blue">="xsd:string"&gt;<br /></span></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">                     <span style="COLOR: blue">&lt;</span><span style="COLOR: maroon">xsd:pattern</span><span style="COLOR: fuchsia"></span><span style="COLOR: red">value</span><span style="COLOR: blue">="\p{L}[\p{L}\p{P}0-9\s]*"</span><span style="COLOR: fuchsia"></span><span style="COLOR: blue">/&gt;<br /></span></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">              <span style="COLOR: blue">&lt;/</span><span style="COLOR: maroon">xsd:restriction</span><span style="COLOR: blue">&gt;<br /></span></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">    <span style="COLOR: blue">&lt;/</span><span style="COLOR: maroon">xsd:simpleType</span><span style="COLOR: blue">&gt;<br />
    &lt;</span><span style="COLOR: maroon">xsd:complexType</span><span style="COLOR: fuchsia"></span><span style="COLOR: red">name</span><span style="COLOR: blue">="addressType"&gt;<br /></span></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">              <span style="COLOR: blue">&lt;</span><span style="COLOR: maroon">xsd:sequence</span><span style="COLOR: blue">&gt;<br /></span></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">                     <span style="COLOR: blue">&lt;</span><span style="COLOR: maroon">xsd:element</span><span style="COLOR: fuchsia"></span><span style="COLOR: red">name</span><span style="COLOR: blue">="City"&gt;<br /></span></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">                            <span style="COLOR: blue">&lt;</span><span style="COLOR: maroon">xsd:simpleType</span><span style="COLOR: blue">&gt;<br /></span></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">                                   <span style="COLOR: blue">&lt;</span><span style="COLOR: maroon">xsd:restriction</span><span style="COLOR: fuchsia"></span><span style="COLOR: red">base</span><span style="COLOR: blue">="nameType"&gt;<br /></span></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">                                          <span style="COLOR: blue">&lt;</span><span style="COLOR: maroon">xsd:maxLength</span><span style="COLOR: fuchsia"></span><span style="COLOR: red">value</span><span style="COLOR: blue">="80"</span><span style="COLOR: fuchsia"></span><span style="COLOR: blue">/&gt;<br /></span></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">                                   <span style="COLOR: blue">&lt;/</span><span style="COLOR: maroon">xsd:restriction</span><span style="COLOR: blue">&gt;<br /></span></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">                            <span style="COLOR: blue">&lt;/</span><span style="COLOR: maroon">xsd:simpleType</span><span style="COLOR: blue">&gt;<br /></span></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">                     <span style="COLOR: blue">&lt;/</span><span style="COLOR: maroon">xsd:element</span><span style="COLOR: blue">&gt;<br /></span></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">                     <span style="COLOR: blue">&lt;</span><span style="COLOR: maroon">xsd:element</span><span style="COLOR: fuchsia"></span><span style="COLOR: red">name</span><span style="COLOR: blue">="Country"</span><span style="COLOR: fuchsia"></span><span style="COLOR: red">type</span><span style="COLOR: blue">="countryNameType"</span><span style="COLOR: fuchsia"></span><span style="COLOR: blue">/&gt;<br /></span></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">                     <span style="COLOR: blue">&lt;</span><span style="COLOR: maroon">xsd:element</span><span style="COLOR: fuchsia"></span><span style="COLOR: red">name</span><span style="COLOR: blue">="CountryCode"</span><span style="COLOR: fuchsia"></span><span style="COLOR: red">type</span><span style="COLOR: blue">="countryCodeType"</span><span style="COLOR: fuchsia"></span><span style="COLOR: blue">/&gt;<br /></span></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">                     <span style="COLOR: blue">&lt;</span><span style="COLOR: maroon">xsd:element</span><span style="COLOR: fuchsia"></span><span style="COLOR: red">name</span><span style="COLOR: blue">="PostalCode"&gt;<br /></span></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">                            <span style="COLOR: blue">&lt;</span><span style="COLOR: maroon">xsd:simpleType</span><span style="COLOR: blue">&gt;<br /></span></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">                                   <span style="COLOR: blue">&lt;</span><span style="COLOR: maroon">xsd:restriction</span><span style="COLOR: fuchsia"></span><span style="COLOR: red">base</span><span style="COLOR: blue">="xsd:string"&gt;<br /></span></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">                                          <span style="COLOR: blue">&lt;</span><span style="COLOR: maroon">xsd:maxLength</span><span style="COLOR: fuchsia"></span><span style="COLOR: red">value</span><span style="COLOR: blue">="10"</span><span style="COLOR: fuchsia"></span><span style="COLOR: blue">/&gt;<br /></span></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">                                   <span style="COLOR: blue">&lt;/</span><span style="COLOR: maroon">xsd:restriction</span><span style="COLOR: blue">&gt;<br /></span></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">                            <span style="COLOR: blue">&lt;/</span><span style="COLOR: maroon">xsd:simpleType</span><span style="COLOR: blue">&gt;<br /></span></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">                     <span style="COLOR: blue">&lt;/</span><span style="COLOR: maroon">xsd:element</span><span style="COLOR: blue">&gt;<br /></span></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">                     <span style="COLOR: blue">&lt;</span><span style="COLOR: maroon">xsd:element</span><span style="COLOR: fuchsia"></span><span style="COLOR: red">name</span><span style="COLOR: blue">="AddressLine"&gt;<br /></span></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">                            <span style="COLOR: blue">&lt;</span><span style="COLOR: maroon">xsd:simpleType</span><span style="COLOR: blue">&gt;<br /></span></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">                                   <span style="COLOR: blue">&lt;</span><span style="COLOR: maroon">xsd:restriction</span><span style="COLOR: fuchsia"></span><span style="COLOR: red">base</span><span style="COLOR: blue">="xsd:string"&gt;<br /></span></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">                                          <span style="COLOR: blue">&lt;</span><span style="COLOR: maroon">xsd:maxLength</span><span style="COLOR: fuchsia"></span><span style="COLOR: red">value</span><span style="COLOR: blue">="160"</span><span style="COLOR: fuchsia"></span><span style="COLOR: blue">/&gt;<br /></span></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">                                   <span style="COLOR: blue">&lt;/</span><span style="COLOR: maroon">xsd:restriction</span><span style="COLOR: blue">&gt;<br /></span></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">                            <span style="COLOR: blue">&lt;/</span><span style="COLOR: maroon">xsd:simpleType</span><span style="COLOR: blue">&gt;<br /></span></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">                     <span style="COLOR: blue">&lt;/</span><span style="COLOR: maroon">xsd:element</span><span style="COLOR: blue">&gt;<br /></span></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">             
&lt;/<span style="COLOR: maroon">xsd:sequence</span>&gt;<br />
       &lt;/<span style="COLOR: maroon">xsd:complexType</span>&gt;</span>
          </p>
          <p>
The restrictions are expressed differently, but they are aspects of type in both cases
and semantically identical. And both cases work and even the regular expressions are
identical. All the sexiness of this example aside, there’s one thing that bugs me:
</p>
          <p>
In XSD, I can create a new simple type by extending a base type with additional metadata
like this
</p>
          <p class="MsoNormal">
            <span style="FONT-SIZE: 8pt; COLOR: blue; FONT-FAMILY: 'Courier New'">&lt;</span>
            <span style="FONT-SIZE: 8pt; COLOR: maroon; FONT-FAMILY: 'Courier New'">xsd:simpleType</span>
            <span style="FONT-SIZE: 8pt; COLOR: fuchsia; FONT-FAMILY: 'Courier New'">
            </span>
            <span style="FONT-SIZE: 8pt; COLOR: red; FONT-FAMILY: 'Courier New'">name</span>
            <span style="FONT-SIZE: 8pt; COLOR: blue; FONT-FAMILY: 'Courier New'">="nameType"&gt;<br /></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">       <span style="COLOR: blue">&lt;</span><span style="COLOR: maroon">xsd:restriction</span><span style="COLOR: fuchsia"></span><span style="COLOR: red">base</span><span style="COLOR: blue">="xsd:string"&gt;<br /></span></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">              <span style="COLOR: blue">&lt;</span><span style="COLOR: maroon">xsd:pattern</span><span style="COLOR: fuchsia"></span><span style="COLOR: red">value</span><span style="COLOR: blue">="\p{L}[\p{L}\p{P}0-9\s]*"</span><span style="COLOR: fuchsia"></span><span style="COLOR: blue">/&gt;<br /></span></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">      
&lt;/<span style="COLOR: maroon">xsd:restriction</span>&gt;<br />
&lt;/<span style="COLOR: maroon">xsd:simpleType</span>&gt;</span>
          </p>
          <p>
which causes the metadata to be inherited by the subsequent element definition that
again uses metadata to further augment the type definition with metadata rules:
</p>
          <p class="MsoNormal">
            <span style="FONT-SIZE: 8pt; COLOR: blue; FONT-FAMILY: 'Courier New'">&lt;</span>
            <span style="FONT-SIZE: 8pt; COLOR: maroon; FONT-FAMILY: 'Courier New'">xsd:element</span>
            <span style="FONT-SIZE: 8pt; COLOR: fuchsia; FONT-FAMILY: 'Courier New'">
            </span>
            <span style="FONT-SIZE: 8pt; COLOR: red; FONT-FAMILY: 'Courier New'">name</span>
            <span style="FONT-SIZE: 8pt; COLOR: blue; FONT-FAMILY: 'Courier New'">="City"&gt;<br /></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">       <span style="COLOR: blue">&lt;</span><span style="COLOR: maroon">xsd:simpleType</span><span style="COLOR: blue">&gt;<br /></span></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">              <span style="COLOR: blue">&lt;</span><span style="COLOR: maroon">xsd:restriction</span><span style="COLOR: fuchsia"></span><span style="COLOR: red">base</span><span style="COLOR: blue">="nameType"&gt;<br /></span></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">                     <span style="COLOR: blue">&lt;</span><span style="COLOR: maroon">xsd:maxLength</span><span style="COLOR: fuchsia"></span><span style="COLOR: red">value</span><span style="COLOR: blue">="80"</span><span style="COLOR: fuchsia"></span><span style="COLOR: blue">/&gt;<br /></span></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">              <span style="COLOR: blue">&lt;/</span><span style="COLOR: maroon">xsd:restriction</span><span style="COLOR: blue">&gt;<br /></span></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">      
&lt;/<span style="COLOR: maroon">xsd:simpleType</span>&gt;<br />
&lt;/<span style="COLOR: maroon">xsd:element</span>&gt;</span>
          </p>
          <p>
So, XSD knows how to do metadata inheritance on simple types. The basic storage type
(xsd:string) isn’t changed by this augmentation, it’s just the validation rules that
change, expressed by adding metadata to the type. The problem is that the CLR model
isn’t directly compatible with this. You can’t derive from any of the simple types
and therefore you can’t project this schema directly onto a CLR type definition. Therefore
I will have to apply the metadata onto every field/property, which is the equivalent
of the XSD’s element declaration. The luxury of the &lt;xsd:simpleType/&gt; definition
and inheritable metadata doesn’t exist. Or does it?
</p>
          <p>
Well, using the following pattern it indeed can. Almost.
</p>
          <p>
Let’s forget for a little moment that the <i>nameType</i> simple type definition above
is a restriction of xsd:string, but let’s focus on what it really does for us. It
encapsulates metadata. When we inherit that into the <i>City</i> element, an additional
metadata item is added, resulting in a metadata composite of two rules – applied to
the base type xsd:string.
</p>
          <p>
So the about equivalent of this expressed in CLR terms could look like this:
</p>
          <p class="MsoNormal">
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">    [AttributeUsage(AttributeTargets.Field)]<br /></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">    [Match(@"\p{L}[\p{L}\p{P}0-9\s]+")]<br /></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">    <span style="COLOR: blue">public</span><span style="COLOR: blue">class</span> NameTypeStringAttribute
: Attribute<br /></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">    {<br /></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">    }</span>
          </p>
          <p class="MsoNormal">
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">    [System.Xml.Serialization.XmlTypeAttribute(<br />
       Namespace="urn:schemas-newtelligence-com:transactionsamples:customerdata:v1")]<br /></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">    <span style="COLOR: blue">public</span><span style="COLOR: blue">class</span> addressType<br /></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">    {<br /></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">        [<b>NameTypeString</b>,MaxLength(80)]<br />
        <span style="COLOR: blue">public</span><span style="COLOR: blue">string</span> City;<br />
        
<br />
        …<br />
    }</span>
          </p>
          <p>
Now we have an attribute NameTypeString(Attribute) that fulfills the same metadata
containment function. The attribute has an attribute. In fact, we could even go further
with this and introduce a dedicated “CityString” meta-type either by composition:
</p>
          <p class="MsoNormal">
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">   [AttributeUsage(AttributeTargets.Field)]<br />
   [<b>NameTypeString</b>,MaxLength(80)]</span>
            <br />
      <span style="FONT-SIZE: 8pt; COLOR: blue; FONT-FAMILY: 'Courier New'">public</span><span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"><span style="COLOR: blue">class</span> CityStringAttribute
: Attribute<br /></span><span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">    {</span></p>
          <p class="MsoNormal">
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">    }</span>
          </p>
          <p>
 … or by inheritance
</p>
          <p class="MsoNormal">
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">    [AttributeUsage(AttributeTargets.Field)]<br />
    [MaxLength(80)]</span>
            <br />
       <span style="FONT-SIZE: 8pt; COLOR: blue; FONT-FAMILY: 'Courier New'">public</span><span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"><span style="COLOR: blue">class</span> CityStringAttribute
: NameTypeStringAttribute<br /></span><span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">    {<br /></span><span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">    }</span></p>
          <p>
Resulting in the simple field declaration
</p>
          <p>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">    [<b>CityString</b>] <span style="COLOR: blue">public</span><span style="COLOR: blue">string</span> City;</span>
          </p>
          <p>
The declaration essentially tells us “stored as a string, following the contract rules
as defined in the composite metadata of [CityString]”.
</p>
          <p>
Having that, there is one thing that’s still missing. How does the infrastructure
tell if an attribute is indeed a composite and that the applicable set of metadata
is a combination of all attributes found on this attribute and attributes that are
declared on itself?
</p>
          <p>
The answer is the following innocent looking marker interface:
</p>
          <p class="MsoNormal">
            <span style="FONT-SIZE: 8pt; COLOR: blue; FONT-FAMILY: 'Courier New'">   
public</span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">
              <span style="COLOR: blue">interface</span> ICompositeAttribute<br /></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">    {</span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">  }</span>
          </p>
          <p>
If that marker interface is found on an attribute, the attribute is considered a composite
attribute and the infrastructure must (potentially recursively) consider attributes
defined on this attribute in the same way as attributes that exist on the originally
inspected element – for instance, a field.
</p>
          <p class="MsoNormal">
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">    [AttributeUsage(AttributeTargets.Field)]<br /></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">    [Match(@"\p{L}[\p{L}\p{P}0-9\s]+")]<br /></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">    <span style="COLOR: blue">public</span><span style="COLOR: blue">class</span> NameTypeStringAttribute
: Attribute, ICompositeAttribute<br /></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">    {</span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">   }</span>
          </p>
          <p>
Why a marker interface and not just another attribute on the attribute? The answer
is quite simple: Convenience. Using the marker interface, you can find composites
simply with the following expression: *.GetCustomAttributes(typeof(ICompositeAttribute),true)
</p>
          <p>
And why not use a base-class “CompositeAttribute”? Because that would be an unnecessary
restriction for the composition of attributes. If only the marker interface is used,
the composite can have any base attribute class, including those built into the system.
</p>
          <p>
But wait, this is just one side of the composition story for attributes. There’s already
a hint on an additional composition quality two short paragraphs up: *.GetCustomAttributes(typeof(ICompositeAttribute),true).
The metadata search algorithm doesn’t only look for concrete attribute types, but
also looks for interfaces, allowing the above expression to work. 
</p>
          <p>
So how would it be if an infrastructure like Enterprise Services would not use concrete
attributes, but would also support composable attributes as illustrated here …
</p>
          <p class="MsoNormal">
            <span style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Lucida Console'">    </span>
            <span style="FONT-SIZE: 8pt; COLOR: blue; FONT-FAMILY: 'Courier New'">public</span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">
              <span style="COLOR: blue">interface</span> ITransactionAttribute<br /></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">    {<br /></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">        <span style="COLOR: blue">public</span> TransactionOption
TransactionOption<br /></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">        {<br /></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">            <span style="COLOR: blue">get</span>;<br /></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">        }<br /></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">    }</span>
          </p>
          <p class="MsoNormal">
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">    <span style="COLOR: blue">public</span><span style="COLOR: blue">interface</span> IObjectPoolingAttribute<br /></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">    {<br /></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">        <span style="COLOR: blue">public</span><span style="COLOR: blue">int</span> MinPoolSize<br /></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">        {<br /></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">            <span style="COLOR: blue">get</span>;<br /></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">        }</span>
          </p>
          <p class="MsoNormal">
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">        <span style="COLOR: blue">public</span><span style="COLOR: blue">int</span> MaxPoolSize<br /></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">        {<br /></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">            <span style="COLOR: blue">get</span>;<br /></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">        }<br /></span>
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">    }</span>
          </p>
          <p class="MsoNormal">
            <span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'">
            </span> 
</p>
          <p>
In that case, you would also be able to define composite attributes that define standardized
behavior for a certain class of ServicedComponents that you have in your application
and should all behave in a similar way, resulting in a declaration like this:
</p>
          <p class="MsoNormal">
      <span style="FONT-SIZE: 8pt; COLOR: blue; FONT-FAMILY: 'Courier New'">public</span><span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"><span style="COLOR: blue">class</span> StandardTransactionalPooledAttribute
: 
<br />
        Attribute, ITransactionAttribute, IObjectPoolingAttribute<br />
    {<br />
    }<br /></span><br />
      <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">[StandardTransactionalPooled]<br />
    <span style="COLOR: blue">public</span><span style="COLOR: blue">class</span> MyComponent
: ServiceComponent<br /></span><span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">    {</span></p>
          <p class="MsoNormal">
            <span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'">    }</span>
          </p>
          <p>
While it seems to be an “either/or” thing at first, both illustrated composition patterns,
the one using ICompositeAttribute and the other that’s entirely based on the inherent
composition qualities of interface are useful. If you want to reuse a set of pre-built
attributes like the ones that I am using to implement the constraints, the marker
interface solution is very cheap, because the coding effort is minimal. If you are
writing a larger infrastructure and want to allow your users more control over what
attributes do and allow them to provide their own implementation, “interface-based
attributes” may be a better choice. 
</p>
        </div>
        <p>
Download: <a href="http://staff.newtelligence.net/clemensv/content/binary/MetadataTester.zip">MetadataTester.zip</a><br /></p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=d3fbcdef-3387-41c5-a645-df3f6615c1e4" />
      </body>
      <title>Composite Metadata (this will change your life)</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,d3fbcdef-3387-41c5-a645-df3f6615c1e4.aspx</guid>
      <link>http://vasters.com/clemensv/2003/09/25/Composite+Metadata+This+Will+Change+Your+Life.aspx</link>
      <pubDate>Thu, 25 Sep 2003 20:19:55 GMT</pubDate>
      <description>&lt;div class=Section1&gt;
&lt;p&gt;
I am in a blogging mood today … Here are some thoughts around composite metadata.
Sorry for the bold title ;)
&lt;/p&gt;
&lt;p style="TEXT-ALIGN: center" align=center&gt;
* * *
&lt;/p&gt;
&lt;p&gt;
Whenever I am asked what I consider the most important innovation of the CLR, I don’t
hesitate to respond “extensible metadata”&lt;span style="COLOR: navy"&gt; &lt;/span&gt;com&lt;span style="COLOR: navy"&gt;ing&lt;/span&gt; in
the form of custom attributes. Everyone who has followed this blog for a while and
looked at some of the source code I published knows that I am seriously in love with
attributes. In fact, very few of the projects I write don’t include at least one class
derived from &lt;i&gt;Attribute&lt;/i&gt; and once you use the &lt;i&gt;XmlSerializer&lt;/i&gt;, Enterprise
Services or ASMX, there’s no way around using them.
&lt;/p&gt;
&lt;p&gt;
In my keynote on contracts and metadata at the Norwegian Visual Studio .NET 2003 launch
earlier this year, I used the sample that’s attached at the bottom of this article.
It illustrates how contracts can be enforced by both, schema validation and validation
of object graphs based on the same set of constraints. In schema, the constraints
are defined using metadata (restrictions) inside element or type definitions, and
in classes, the very same restrictions can be applied using custom attributes, given
you have a sufficient set of attributes and the respective validation logic. In both
cases, the data is run through a filter that’s driven by the metadata information.
If either filter is used at the inbound &lt;i&gt;and outbound&lt;/i&gt; channels of a service,
contract enforcement is automatic and “contract trust” between services, as defined
in my &lt;a href="http://staff.newtelligence.net/clemensv/PermaLink.aspx?guid=b379fb50-70b2-48b1-9d56-7cc5377022e5"&gt;previous
article&lt;/a&gt;, can be achieved. So far, so good.
&lt;/p&gt;
&lt;p&gt;
In my example, the metadata instrumentation for a CLR type looks like this:
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;[System.Xml.Serialization.XmlTypeAttribute(&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Namespace="urn:schemas-newtelligence-com:transactionsamples:customerdata:v1")]&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;class&lt;/span&gt; addressType&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
{&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
[Match(@"\p{L}[\p{L}\p{P}0-9\s]*"),MaxLength(80)]&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; City;&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; countryNameType
Country;&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; countryCodeType
CountryCode;&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
[MaxLength(10)]&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; PostalCode;&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
[MaxLength(160)]&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; AddressLine;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
… while the corresponding schema is a bit better factored and looks like this:
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;span style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Lucida Console'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;lt;&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; COLOR: maroon; FONT-FAMILY: 'Courier New'"&gt;xsd:simpleType&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; COLOR: fuchsia; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; COLOR: red; FONT-FAMILY: 'Courier New'"&gt;name&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;="nameType"&amp;gt;&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;xsd:restriction&lt;/span&gt;&lt;span style="COLOR: fuchsia"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;base&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="xsd:string"&amp;gt;&lt;br&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;xsd:pattern&lt;/span&gt;&lt;span style="COLOR: fuchsia"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;value&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="\p{L}[\p{L}\p{P}0-9\s]*"&lt;/span&gt;&lt;span style="COLOR: fuchsia"&gt; &lt;/span&gt;&lt;span style="COLOR: blue"&gt;/&amp;gt;&lt;br&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;xsd:restriction&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;br&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;xsd:simpleType&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;xsd:complexType&lt;/span&gt;&lt;span style="COLOR: fuchsia"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;name&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="addressType"&amp;gt;&lt;br&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;xsd:sequence&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;br&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;xsd:element&lt;/span&gt;&lt;span style="COLOR: fuchsia"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;name&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="City"&amp;gt;&lt;br&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;xsd:simpleType&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;br&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;xsd:restriction&lt;/span&gt;&lt;span style="COLOR: fuchsia"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;base&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="nameType"&amp;gt;&lt;br&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;xsd:maxLength&lt;/span&gt;&lt;span style="COLOR: fuchsia"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;value&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="80"&lt;/span&gt;&lt;span style="COLOR: fuchsia"&gt; &lt;/span&gt;&lt;span style="COLOR: blue"&gt;/&amp;gt;&lt;br&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;xsd:restriction&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;br&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;xsd:simpleType&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;br&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;xsd:element&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;br&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;xsd:element&lt;/span&gt;&lt;span style="COLOR: fuchsia"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;name&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="Country"&lt;/span&gt;&lt;span style="COLOR: fuchsia"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;type&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="countryNameType"&lt;/span&gt;&lt;span style="COLOR: fuchsia"&gt; &lt;/span&gt;&lt;span style="COLOR: blue"&gt;/&amp;gt;&lt;br&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;xsd:element&lt;/span&gt;&lt;span style="COLOR: fuchsia"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;name&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="CountryCode"&lt;/span&gt;&lt;span style="COLOR: fuchsia"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;type&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="countryCodeType"&lt;/span&gt;&lt;span style="COLOR: fuchsia"&gt; &lt;/span&gt;&lt;span style="COLOR: blue"&gt;/&amp;gt;&lt;br&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;xsd:element&lt;/span&gt;&lt;span style="COLOR: fuchsia"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;name&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="PostalCode"&amp;gt;&lt;br&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;xsd:simpleType&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;br&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;xsd:restriction&lt;/span&gt;&lt;span style="COLOR: fuchsia"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;base&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="xsd:string"&amp;gt;&lt;br&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;xsd:maxLength&lt;/span&gt;&lt;span style="COLOR: fuchsia"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;value&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="10"&lt;/span&gt;&lt;span style="COLOR: fuchsia"&gt; &lt;/span&gt;&lt;span style="COLOR: blue"&gt;/&amp;gt;&lt;br&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;xsd:restriction&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;br&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;xsd:simpleType&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;br&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;xsd:element&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;br&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;xsd:element&lt;/span&gt;&lt;span style="COLOR: fuchsia"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;name&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="AddressLine"&amp;gt;&lt;br&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;xsd:simpleType&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;br&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;xsd:restriction&lt;/span&gt;&lt;span style="COLOR: fuchsia"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;base&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="xsd:string"&amp;gt;&lt;br&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;xsd:maxLength&lt;/span&gt;&lt;span style="COLOR: fuchsia"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;value&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="160"&lt;/span&gt;&lt;span style="COLOR: fuchsia"&gt; &lt;/span&gt;&lt;span style="COLOR: blue"&gt;/&amp;gt;&lt;br&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;xsd:restriction&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;br&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;xsd:simpleType&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;br&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;xsd:element&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;br&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;/&lt;span style="COLOR: maroon"&gt;xsd:sequence&lt;/span&gt;&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;span style="COLOR: maroon"&gt;xsd:complexType&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
The restrictions are expressed differently, but they are aspects of type in both cases
and semantically identical. And both cases work and even the regular expressions are
identical. All the sexiness of this example aside, there’s one thing that bugs me:
&lt;/p&gt;
&lt;p&gt;
In XSD, I can create a new simple type by extending a base type with additional metadata
like this
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;span style="FONT-SIZE: 8pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;lt;&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; COLOR: maroon; FONT-FAMILY: 'Courier New'"&gt;xsd:simpleType&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; COLOR: fuchsia; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; COLOR: red; FONT-FAMILY: 'Courier New'"&gt;name&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;="nameType"&amp;gt;&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;xsd:restriction&lt;/span&gt;&lt;span style="COLOR: fuchsia"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;base&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="xsd:string"&amp;gt;&lt;br&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;xsd:pattern&lt;/span&gt;&lt;span style="COLOR: fuchsia"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;value&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="\p{L}[\p{L}\p{P}0-9\s]*"&lt;/span&gt;&lt;span style="COLOR: fuchsia"&gt; &lt;/span&gt;&lt;span style="COLOR: blue"&gt;/&amp;gt;&lt;br&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;/&lt;span style="COLOR: maroon"&gt;xsd:restriction&lt;/span&gt;&amp;gt;&lt;br&gt;
&amp;lt;/&lt;span style="COLOR: maroon"&gt;xsd:simpleType&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
which causes the metadata to be inherited by the subsequent element definition that
again uses metadata to further augment the type definition with metadata rules:
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;span style="FONT-SIZE: 8pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;lt;&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; COLOR: maroon; FONT-FAMILY: 'Courier New'"&gt;xsd:element&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; COLOR: fuchsia; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; COLOR: red; FONT-FAMILY: 'Courier New'"&gt;name&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;="City"&amp;gt;&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;xsd:simpleType&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;br&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;xsd:restriction&lt;/span&gt;&lt;span style="COLOR: fuchsia"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;base&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="nameType"&amp;gt;&lt;br&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;xsd:maxLength&lt;/span&gt;&lt;span style="COLOR: fuchsia"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;value&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="80"&lt;/span&gt;&lt;span style="COLOR: fuchsia"&gt; &lt;/span&gt;&lt;span style="COLOR: blue"&gt;/&amp;gt;&lt;br&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;xsd:restriction&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;br&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;/&lt;span style="COLOR: maroon"&gt;xsd:simpleType&lt;/span&gt;&amp;gt;&lt;br&gt;
&amp;lt;/&lt;span style="COLOR: maroon"&gt;xsd:element&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
So, XSD knows how to do metadata inheritance on simple types. The basic storage type
(xsd:string) isn’t changed by this augmentation, it’s just the validation rules that
change, expressed by adding metadata to the type. The problem is that the CLR model
isn’t directly compatible with this. You can’t derive from any of the simple types
and therefore you can’t project this schema directly onto a CLR type definition. Therefore
I will have to apply the metadata onto every field/property, which is the equivalent
of the XSD’s element declaration. The luxury of the &amp;lt;xsd:simpleType/&amp;gt; definition
and inheritable metadata doesn’t exist. Or does it?
&lt;/p&gt;
&lt;p&gt;
Well, using the following pattern it indeed can. Almost.
&lt;/p&gt;
&lt;p&gt;
Let’s forget for a little moment that the &lt;i&gt;nameType&lt;/i&gt; simple type definition above
is a restriction of xsd:string, but let’s focus on what it really does for us. It
encapsulates metadata. When we inherit that into the &lt;i&gt;City&lt;/i&gt; element, an additional
metadata item is added, resulting in a metadata composite of two rules – applied to
the base type xsd:string.
&lt;/p&gt;
&lt;p&gt;
So the about equivalent of this expressed in CLR terms could look like this:
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [AttributeUsage(AttributeTargets.Field)]&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[Match(@"\p{L}[\p{L}\p{P}0-9\s]+")]&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;class&lt;/span&gt; NameTypeStringAttribute
: Attribute&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[System.Xml.Serialization.XmlTypeAttribute(&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Namespace="urn:schemas-newtelligence-com:transactionsamples:customerdata:v1")]&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;class&lt;/span&gt; addressType&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[&lt;b&gt;NameTypeString&lt;/b&gt;,MaxLength(80)]&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; City;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; …&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt; 
&lt;/p&gt;
&lt;p&gt;
Now we have an attribute NameTypeString(Attribute) that fulfills the same metadata
containment function. The attribute has an attribute. In fact, we could even go further
with this and introduce a dedicated “CityString” meta-type either by composition:
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp; [AttributeUsage(AttributeTargets.Field)]&lt;br&gt;
&amp;nbsp;&amp;nbsp; [&lt;b&gt;NameTypeString&lt;/b&gt;,MaxLength(80)]&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="FONT-SIZE: 8pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;public&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt; &lt;span style="COLOR: blue"&gt;class&lt;/span&gt; CityStringAttribute
: Attribute&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;… or by inheritance
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;[AttributeUsage(AttributeTargets.Field)]&lt;br&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;[MaxLength(80)]&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;span style="FONT-SIZE: 8pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;public&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt; &lt;span style="COLOR: blue"&gt;class&lt;/span&gt; CityStringAttribute
: NameTypeStringAttribute&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
Resulting in the simple field declaration
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;b&gt;CityString&lt;/b&gt;] &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; City;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
The declaration essentially tells us “stored as a string, following the contract rules
as defined in the composite metadata of [CityString]”.
&lt;/p&gt;
&lt;p&gt;
Having that, there is one thing that’s still missing. How does the infrastructure
tell if an attribute is indeed a composite and that the applicable set of metadata
is a combination of all attributes found on this attribute and attributes that are
declared on itself?
&lt;/p&gt;
&lt;p&gt;
The answer is the following innocent looking marker interface:
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;span style="FONT-SIZE: 8pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
public&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt; &lt;span style="COLOR: blue"&gt;interface&lt;/span&gt; ICompositeAttribute&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
If that marker interface is found on an attribute, the attribute is considered a composite
attribute and the infrastructure must (potentially recursively) consider attributes
defined on this attribute in the same way as attributes that exist on the originally
inspected element – for instance, a field.
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [AttributeUsage(AttributeTargets.Field)]&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[Match(@"\p{L}[\p{L}\p{P}0-9\s]+")]&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;class&lt;/span&gt; NameTypeStringAttribute
: Attribute, ICompositeAttribute&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
Why a marker interface and not just another attribute on the attribute? The answer
is quite simple: Convenience. Using the marker interface, you can find composites
simply with the following expression: *.GetCustomAttributes(typeof(ICompositeAttribute),true)
&lt;/p&gt;
&lt;p&gt;
And why not use a base-class “CompositeAttribute”? Because that would be an unnecessary
restriction for the composition of attributes. If only the marker interface is used,
the composite can have any base attribute class, including those built into the system.
&lt;/p&gt;
&lt;p&gt;
But wait, this is just one side of the composition story for attributes. There’s already
a hint on an additional composition quality two short paragraphs up: *.GetCustomAttributes(typeof(ICompositeAttribute),true).
The metadata search algorithm doesn’t only look for concrete attribute types, but
also looks for interfaces, allowing the above expression to work. 
&lt;/p&gt;
&lt;p&gt;
So how would it be if an infrastructure like Enterprise Services would not use concrete
attributes, but would also support composable attributes as illustrated here …
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;span style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Lucida Console'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;public&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt; &lt;span style="COLOR: blue"&gt;interface&lt;/span&gt; ITransactionAttribute&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="COLOR: blue"&gt;public&lt;/span&gt; TransactionOption
TransactionOption&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="COLOR: blue"&gt;get&lt;/span&gt;;&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;interface&lt;/span&gt; IObjectPoolingAttribute&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;int&lt;/span&gt; MinPoolSize&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="COLOR: blue"&gt;get&lt;/span&gt;;&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;int&lt;/span&gt; MaxPoolSize&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="COLOR: blue"&gt;get&lt;/span&gt;;&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'"&gt;&lt;/span&gt;&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
In that case, you would also be able to define composite attributes that define standardized
behavior for a certain class of ServicedComponents that you have in your application
and should all behave in a similar way, resulting in a declaration like this:
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="FONT-SIZE: 8pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;public&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt; &lt;span style="COLOR: blue"&gt;class&lt;/span&gt; StandardTransactionalPooledAttribute
: 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Attribute, ITransactionAttribute, IObjectPoolingAttribute&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;[StandardTransactionalPooled]&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;class&lt;/span&gt; MyComponent
: ServiceComponent&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
While it seems to be an “either/or” thing at first, both illustrated composition patterns,
the one using ICompositeAttribute and the other that’s entirely based on the inherent
composition qualities of interface are useful. If you want to reuse a set of pre-built
attributes like the ones that I am using to implement the constraints, the marker
interface solution is very cheap, because the coding effort is minimal. If you are
writing a larger infrastructure and want to allow your users more control over what
attributes do and allow them to provide their own implementation, “interface-based
attributes” may be a better choice. 
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
Download: &lt;a href="http://staff.newtelligence.net/clemensv/content/binary/MetadataTester.zip"&gt;MetadataTester.zip&lt;/a&gt;
&lt;br&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=d3fbcdef-3387-41c5-a645-df3f6615c1e4" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,d3fbcdef-3387-41c5-a645-df3f6615c1e4.aspx</comments>
      <category>Architecture</category>
      <category>Technology/CLR</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=91217202-8d08-4330-9163-1143acbe8259</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,91217202-8d08-4330-9163-1143acbe8259.aspx</pingback:target>
      <dc:creator />
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,91217202-8d08-4330-9163-1143acbe8259.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=91217202-8d08-4330-9163-1143acbe8259</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
While I wasn't looking, <a href="http://www.douglasp.com/2003/08/15.html#a351">Doug
Purdy</a>, who is the PM for the team in charge of the XmlSerializer
has posted this little cryptic answer to my initial question:
</p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
            <font face="Courier New,Courier, Monospace" size="2">String serializedDateTime = XmlConvert.ToString(
someDateTime ); </font>
          </p>
          <p>
            <font face="Courier New,Courier, Monospace" size="2">DateTime deserializedDateTime
= XmlConvert.ToDateTime( serializedDateTime );</font>
          </p>
        </blockquote>
        <p>
What Doug is showing is really what the serializer is doing with dates under the hood
and that I am incorrectly <a href="http://staff.newtelligence.net/clemensv/PermaLink.aspx?guid=77bd9cef-bfeb-464c-bc72-2c849e1e8616">blaming</a> the
XmlSerializer for the lack of UTC support. [XmlConvert.ToString() also does nothing
more than calling DateTime.ToString() with the appropriate format string]. As I was
already saying in yesterday's post, but what I want to make a bit clearer here again
is that the actual problem is the lack of time-zone awareness in DateTime. 
</p>
        <p>
So the proper thing more me to do is to ask the base-class library team for time-zone
support in the base-class library for Whidbey so that Doug can fix this for us
;)
</p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=91217202-8d08-4330-9163-1143acbe8259" />
      </body>
      <title>XmlSerializer &amp; UTC once more</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,91217202-8d08-4330-9163-1143acbe8259.aspx</guid>
      <link>http://vasters.com/clemensv/2003/08/20/XmlSerializer+UTC+Once+More.aspx</link>
      <pubDate>Wed, 20 Aug 2003 13:43:30 GMT</pubDate>
      <description>&lt;p&gt;
While&amp;nbsp;I wasn't looking, &lt;a href="http://www.douglasp.com/2003/08/15.html#a351"&gt;Doug
Purdy&lt;/a&gt;,&amp;nbsp;who is the&amp;nbsp;PM for the&amp;nbsp;team in charge&amp;nbsp;of the XmlSerializer
has posted this little cryptic answer to my initial question:
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p&gt;
&lt;font face="Courier New,Courier, Monospace" size=2&gt;String serializedDateTime = XmlConvert.ToString(
someDateTime ); &lt;/font&gt; 
&lt;p&gt;
&lt;font face="Courier New,Courier, Monospace" size=2&gt;DateTime deserializedDateTime =
XmlConvert.ToDateTime( serializedDateTime );&lt;/font&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
What Doug is showing is really what the serializer is doing with dates under the hood
and that I am incorrectly &lt;a href="http://staff.newtelligence.net/clemensv/PermaLink.aspx?guid=77bd9cef-bfeb-464c-bc72-2c849e1e8616"&gt;blaming&lt;/a&gt; the
XmlSerializer for the lack of UTC support. [XmlConvert.ToString() also does nothing
more than calling DateTime.ToString() with the appropriate format string]. As I was
already saying in yesterday's post, but what I want to make a bit clearer here again
is that the actual problem is the lack of time-zone awareness in DateTime. 
&lt;/p&gt;
&lt;p&gt;
So the proper thing more me to do is to ask the base-class library team&amp;nbsp;for time-zone
support in the base-class library for Whidbey so that Doug can fix&amp;nbsp;this for us
;)
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=91217202-8d08-4330-9163-1143acbe8259" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,91217202-8d08-4330-9163-1143acbe8259.aspx</comments>
      <category>Technology/XML</category>
      <category>Technology/CLR</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=77bd9cef-bfeb-464c-bc72-2c849e1e8616</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,77bd9cef-bfeb-464c-bc72-2c849e1e8616.aspx</pingback:target>
      <dc:creator />
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,77bd9cef-bfeb-464c-bc72-2c849e1e8616.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=77bd9cef-bfeb-464c-bc72-2c849e1e8616</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I posted a little question <a href="http://staff.newtelligence.net/clemensv/PermaLink.aspx?guid=39ed85fd-bd6d-4dd9-b5e1-a56bf3847f6a">here</a>,
just asking "Why?". For your reading convenience, I pull the code in here once more:
</p>
        <p class="MsoNormal" style="MARGIN-BOTTOM: 12pt">
          <span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'">DateTime issued;</span>
        </p>
        <p class="MsoNormal">
          <span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'">[XmlIgnore]<br /></span>
          <span style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Lucida Console'">public</span>
          <span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'"> DateTime
IssuedUtc 
<br />
{ <span style="COLOR: blue">get</span> { <span style="COLOR: blue">return</span> issued;
} <span style="COLOR: blue">set</span> { issued = <span style="COLOR: blue">value</span>;
} }<br /><br />
[XmlElement("issued")]<br /><span style="COLOR: blue">public</span> DateTime IssuedLocalTime 
<br />
{ <span style="COLOR: blue">get</span> { <span style="COLOR: blue">return</span> Issued.ToLocalTime();
} <span style="COLOR: blue">set</span> { Issued = <span style="COLOR: blue">value</span>.ToUniversalTime();
} }</span>
        </p>
        <p>
So, indeed, why am I doing this? Well, when I decided to normalize all times
handled by the backend engine of dasBlog into the UTC timezone, I really didn't
think of the XML Serializer being a problem at first. It turned out to be one. 
</p>
        <p>
The reason why I wanted all times to be handled internally as UTC is quite
simple: Too many time zones to deal with and I need to have a proper reference to
do forward and backward time calculations. dasBlog deals with four time-zones: 
</p>
        <ul>
          <li>
            <strong>"Reader Time":</strong> The "&lt;%userWhen%&gt; macro emits a block of script
that will cause the browser to emit the time of a post local to the reader's time
zone. That one is easy, because the calculation happens on the client, but I need
to feed it UTC (GMT). 
</li>
          <li>
            <strong>"Display Time"</strong>: This is the time zone the blog owner selects for
his/her blog. All times displayed on the weblog pages are shown in that time zone
(complete with the TZ name and the GMT offset). This also applies to the
"admin pages" such as referrals and events (which both roll over in synch with
the display time zone). Display time is calculated dynamically and you will notice
that it also automatically adjusts for daylight savings time. The display time zone
is also by no means fixed. If the blog author travels (and you will see this on my
blog starting next week), he/she can adjust the blog to his/her present time
zone. When I am going to be at TechEd Malaysia, my blog will show UTC+0800. To
make this time-zone shifting work, the absolute time must be stored in UTC. 
</li>
          <li>
            <strong>"Engine Time": </strong>This is UTC. All of the dasBlog runtime handles everything
in UTC. 
</li>
          <li>
            <strong>"Server Time":</strong> Now were getting to the point. The engine runs on
a server that has it's own local time zone setting: "server local time". That's something
that the user who's running his engine at some ISP can't control and that's the one
of all the time zones that really nobody is ever interested in. You shouldn't care
whether your blog is hosted in Germany, the U.S. East Coast or Singapore. That's even
more of an issue because one could expect that hosted sites may get moved around between
ISP locations. The only little thing we're interested in is that the server knows
its offset to UTC.</li>
        </ul>
        <p>
So ... I was thinking.... ask for DateTime.Now.ToUniversalTime(), handle everything
in UTC from there on and everything's good. (Btw, I know about DateTime.UtcNow,
but I like the expressiveness of this better).
</p>
        <p>
What I wasn't considering is the way the XmlSerializer works, which I am using both
for storage and for the various web services (including the Atom feed). What I also
found is that the DateTime class in the framework isn't time-zone aware.
</p>
        <p>
The workaround above is used because the XML Serialization infrastructure <strong>always</strong> assumes
local time ("Server time") for serialization and will <strong>always </strong>emit
ISO 8601 dates with a time-zone suffix like this: <span class="tx">2003-08-19T15:15:58.0781250+02:00.
So when you are handling UTC times internally and use them blindly with XML serialization
for both storage and web services, the serializer will assume you are using local
time and throw you off by your own time-zone difference to UTC.</span></p>
        <p>
          <span class="tx">This isn't "too bad" when you store stuff in local XML files, because
when you write something wrong from the same place you read it back into and your
time-zones don't change you are in ok in memory, but you are nevertheless wrong on
disk. What happened to me in dasBlog version 1.1 was that I was thinking that I stored
UTC, but in fact I stored everything in local time. My UTC time <span class="tx">2003-08-19T15:15:58
always turned into <span class="tx">2003-08-19T15:15:58</span><strong>+02:00</strong>,<strong></strong>because
the DateTime class doesn't keep time-zone information around that the serializer could
use. Therefore the serializer must always assume local time and that causes the
offset to be emitted. </span>That's of course much worse for UTC+12.</span>
        </p>
        <p>
          <span class="tx">The fix:</span>
        </p>
        <p>
          <span class="tx">The field  </span>
          <span class="tx">
            <span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'">DateTime
issued; </span>
          </span>
          <span class="tx">holds the "engine time", which is always UTC.  </span>
        </p>
        <p>
          <span class="tx">The property </span>
        </p>
        <p>
          <span class="tx">
            <span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'">
            </span>
            <span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'">[XmlIgnore]<br /></span>
            <span style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Lucida Console'">public</span>
            <span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'"> DateTime
IssuedUtc 
<br />
{ <span style="COLOR: blue">get</span> { <span style="COLOR: blue">return</span> issued;
} <span style="COLOR: blue">set</span> { issued = <span style="COLOR: blue">value</span>;
} }</span>
          </span>
        </p>
        <p>
          <span class="tx">wraps this value and is the property that the engine works with internally.
The XmlSerializer is instructed to ignore this value in the serialization process
by declaration of the [XmlIgnore] attribute. Instead, we tell the serializer to look
at the following property, which is not used by the engine itself and also indicates
that by its name suffix "LocalTime", which essentially declares it as "off limits"
for direct access to everyone knowing the project:</span>
        </p>
        <p>
          <span class="tx">
            <span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'">
              <br />
[XmlElement("issued")]<br /><span style="COLOR: blue">public</span> DateTime IssuedLocalTime 
<br />
{ <span style="COLOR: blue">get</span> { <span style="COLOR: blue">return</span> Issued.ToLocalTime();
} <span style="COLOR: blue">set</span> { Issued = <span style="COLOR: blue">value</span>.ToUniversalTime();
} }</span>
          </span>
        </p>
        <p>
          <span class="tx">This property is the one that the serializer grabs and it does the
proper conversion to and from server local time that the serializer requires. The
actual dasBlog code is using a variant of this property that is a bit larger in code
size because it also checks for DateTime.MinValue and DateTime.MaxValue occurrences,
which, depending on the server time zone, would cause the time zone shifting to fail
with an overflow/underflow exception (and no, I am not checking <em>near</em> MinValue
and MaxValue):</span>
        </p>
        <span class="tx">
          <font size="2">
            <p>
              <font face="Lucida Console,Courier New,Courier, Monospace">[XmlElement("Date")]<br /></font>
            </p>
          </font>
          <font face="Lucida Console,Courier New,Courier, Monospace">
            <font color="#0000ff" size="2">public</font>
            <font size="2"> DateTime
DateLocalTime<br />
{ 
<br />
    </font>
            <font color="#0000ff" size="2">get</font>
            <font size="2">
              <br />
    { 
<br />
       </font>
            <font color="#0000ff" size="2">return</font>
            <font size="2"> (DateUtc==DateTime.MinValue||DateUtc==DateTime.MaxValue)?<br />
              
DateUtc:DateUtc.ToLocalTime(); 
<br />
    } 
<br />
    </font>
            <font color="#0000ff" size="2">set</font>
            <font size="2">
              <br />
    { 
<br />
        DateUtc = (</font>
            <font color="#0000ff" size="2">value</font>
            <font size="2">==DateTime.MinValue||</font>
            <font color="#0000ff" size="2">value</font>
            <font size="2">==DateTime.MaxValue)?</font>
            <font color="#0000ff" size="2">
              <br />
                 
value</font>
            <font size="2">:</font>
            <font color="#0000ff" size="2">value</font>
            <font size="2">.Date.ToUniversalTime(); 
<br />
    } 
<br />
}
</font>
          </font>
        </span>
        <p>
          <span class="tx">So, that's why.</span>
        </p>
        <p>
          <span class="tx">Be aware that all of this applies to ASP.NET Web Services, too, and
if you are dealing with multiple time zones are you are using UTC normalized times
in your app, you will have to deal with this. If "server time" makes you happy, you
won't need to worry.</span>
        </p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=77bd9cef-bfeb-464c-bc72-2c849e1e8616" />
      </body>
      <title>XmlSerializer Quiz: The solution</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,77bd9cef-bfeb-464c-bc72-2c849e1e8616.aspx</guid>
      <link>http://vasters.com/clemensv/2003/08/19/XmlSerializer+Quiz+The+Solution.aspx</link>
      <pubDate>Tue, 19 Aug 2003 18:41:11 GMT</pubDate>
      <description>&lt;p&gt;
I&amp;nbsp;posted a little question &lt;a href="http://staff.newtelligence.net/clemensv/PermaLink.aspx?guid=39ed85fd-bd6d-4dd9-b5e1-a56bf3847f6a"&gt;here&lt;/a&gt;,
just asking "Why?". For your reading convenience, I pull the code in here once more:
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN-BOTTOM: 12pt"&gt;
&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'"&gt;DateTime issued;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'"&gt;[XmlIgnore]&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Lucida Console'"&gt;public&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'"&gt; DateTime
IssuedUtc 
&lt;br&gt;
{ &lt;span style="COLOR: blue"&gt;get&lt;/span&gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; issued;
} &lt;span style="COLOR: blue"&gt;set&lt;/span&gt; { issued = &lt;span style="COLOR: blue"&gt;value&lt;/span&gt;;
} }&lt;br&gt;
&lt;br&gt;
[XmlElement("issued")]&lt;br&gt;
&lt;span style="COLOR: blue"&gt;public&lt;/span&gt; DateTime IssuedLocalTime 
&lt;br&gt;
{ &lt;span style="COLOR: blue"&gt;get&lt;/span&gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; Issued.ToLocalTime();
} &lt;span style="COLOR: blue"&gt;set&lt;/span&gt; { Issued = &lt;span style="COLOR: blue"&gt;value&lt;/span&gt;.ToUniversalTime();
} }&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
So, indeed, why am I doing this? Well, when I decided to&amp;nbsp;normalize all times
handled by&amp;nbsp;the backend engine of dasBlog into the UTC timezone, I really didn't
think of the XML Serializer being a problem at first. It turned out to be one. 
&lt;p&gt;
The reason why I wanted&amp;nbsp;all times&amp;nbsp;to be handled internally as UTC is quite
simple: Too many time zones to deal with and I need to have a proper reference to
do forward and backward time calculations. dasBlog deals with four time-zones: 
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;"Reader Time":&lt;/strong&gt; The "&amp;lt;%userWhen%&amp;gt; macro emits a block of script
that will cause the browser to emit the time of a post local to the reader's time
zone. That one is easy, because the calculation happens on the client, but I need
to feed it UTC (GMT). 
&lt;li&gt;
&lt;strong&gt;"Display Time"&lt;/strong&gt;: This is the time zone the blog owner selects for
his/her blog. All times displayed on the weblog pages are shown in that time zone
(complete with&amp;nbsp;the TZ name&amp;nbsp;and the GMT offset). This also&amp;nbsp;applies to&amp;nbsp;the
"admin pages" such as referrals and events (which&amp;nbsp;both roll over in synch with
the display time zone).&amp;nbsp;Display time is calculated dynamically and you will notice
that it also automatically adjusts for daylight savings time. The display time zone
is also by no means fixed. If the blog author travels (and you will see this on my
blog starting next week),&amp;nbsp;he/she can adjust the blog to his/her present time
zone. When I am going to be&amp;nbsp;at TechEd Malaysia,&amp;nbsp;my blog will show UTC+0800.&amp;nbsp;To
make this time-zone shifting&amp;nbsp;work, the absolute time must be stored in UTC. 
&lt;li&gt;
&lt;strong&gt;"Engine Time": &lt;/strong&gt;This is UTC. All of the dasBlog runtime handles everything
in UTC. 
&lt;li&gt;
&lt;strong&gt;"Server Time":&lt;/strong&gt; Now were getting to the point. The engine runs on
a server that has it's own local time zone setting: "server local time". That's something
that the user who's running his engine at some ISP can't control and that's the one
of all the time zones that really nobody is ever interested in. You shouldn't care
whether your blog is hosted in Germany, the U.S. East Coast or Singapore. That's even
more of an issue because one could expect that hosted sites may get moved around between
ISP locations. The only little thing we're interested in is that the server knows
its offset to UTC.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
So ... I was thinking.... ask for DateTime.Now.ToUniversalTime(), handle everything
in UTC from there on and everything's good.&amp;nbsp;(Btw, I know about DateTime.UtcNow,
but I like the expressiveness of this better).
&lt;/p&gt;
&lt;p&gt;
What I wasn't considering is the way the XmlSerializer works, which I am using both
for storage and for the various web services (including the Atom feed). What I also
found is that the DateTime class in the framework isn't time-zone aware.
&lt;/p&gt;
&lt;p&gt;
The workaround above is used because the XML Serialization infrastructure &lt;strong&gt;always&lt;/strong&gt; assumes
local time ("Server time") for serialization and will &lt;strong&gt;always &lt;/strong&gt;emit
ISO 8601 dates with a time-zone suffix like this:&amp;nbsp;&lt;span class=tx&gt;2003-08-19T15:15:58.0781250+02:00.
So when you are handling UTC times internally and use them blindly with XML serialization
for both storage and web services, the serializer will assume you are using local
time and throw you off by your own time-zone difference to UTC.&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span class=tx&gt;This isn't "too bad" when you store stuff in local XML files, because
when you write something wrong from the same place you read it back into and your
time-zones don't change you are in ok in memory, but you are nevertheless wrong on
disk. What happened to me in dasBlog version 1.1 was that I was thinking that I stored
UTC, but in fact I stored everything in local time. My&amp;nbsp;UTC time &lt;span class=tx&gt;2003-08-19T15:15:58
always turned into &lt;span class=tx&gt;2003-08-19T15:15:58&lt;/span&gt;&lt;strong&gt;+02:00&lt;/strong&gt;,&lt;strong&gt; &lt;/strong&gt;because
the DateTime class doesn't keep time-zone information around that the serializer could
use. Therefore the serializer must always assume local time&amp;nbsp;and that causes the
offset to be emitted.&amp;nbsp;&lt;/span&gt;That's of course much worse for UTC+12.&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span class=tx&gt;The fix:&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span class=tx&gt;The field&amp;nbsp; &lt;/span&gt;&lt;span class=tx&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'"&gt;DateTime
issued; &lt;/span&gt;&lt;/span&gt;&lt;span class=tx&gt;holds the "engine time", which is always UTC.&amp;nbsp; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span class=tx&gt;The property &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span class=tx&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'"&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'"&gt;[XmlIgnore]&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Lucida Console'"&gt;public&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'"&gt; DateTime
IssuedUtc 
&lt;br&gt;
{ &lt;span style="COLOR: blue"&gt;get&lt;/span&gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; issued;
} &lt;span style="COLOR: blue"&gt;set&lt;/span&gt; { issued = &lt;span style="COLOR: blue"&gt;value&lt;/span&gt;;
} }&lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span class=tx&gt;wraps this value and is the property that the engine works with internally.
The XmlSerializer is instructed to ignore this value in the serialization process
by declaration of the [XmlIgnore] attribute. Instead, we tell the serializer to look
at the following property, which is not used by the engine itself and also indicates
that by its name suffix "LocalTime", which essentially declares it as "off limits"
for direct access to everyone knowing the project:&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span class=tx&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'"&gt;
&lt;br&gt;
[XmlElement("issued")]&lt;br&gt;
&lt;span style="COLOR: blue"&gt;public&lt;/span&gt; DateTime IssuedLocalTime 
&lt;br&gt;
{ &lt;span style="COLOR: blue"&gt;get&lt;/span&gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; Issued.ToLocalTime();
} &lt;span style="COLOR: blue"&gt;set&lt;/span&gt; { Issued = &lt;span style="COLOR: blue"&gt;value&lt;/span&gt;.ToUniversalTime();
} }&lt;/span&gt;
&lt;/p&gt;
&gt; 
&lt;p&gt;
&lt;span class=tx&gt;This property is the one that the serializer grabs and it does the
proper conversion to and from server local time that the serializer requires. The
actual dasBlog code is using a variant of this property that is a bit larger in code
size because it also checks for DateTime.MinValue and DateTime.MaxValue occurrences,
which, depending on the server time zone, would cause the time zone shifting to fail
with an overflow/underflow exception (and no, I am not checking &lt;em&gt;near&lt;/em&gt; MinValue
and MaxValue):&lt;/span&gt;
&lt;/p&gt;
&lt;span class=tx&gt;&lt;font size=2&gt; 
&lt;p&gt;
&lt;font face="Lucida Console,Courier New,Courier, Monospace"&gt;[XmlElement("Date")]&lt;br&gt;
&lt;/font&gt;
&lt;/font&gt;&lt;font face="Lucida Console,Courier New,Courier, Monospace"&gt;&lt;font color=#0000ff size=2&gt;public&lt;/font&gt;&lt;font size=2&gt; DateTime
DateLocalTime&lt;br&gt;
{ 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font color=#0000ff size=2&gt;get&lt;/font&gt;&lt;font size=2&gt; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; { 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font color=#0000ff size=2&gt;return&lt;/font&gt;&lt;font size=2&gt; (DateUtc==DateTime.MinValue||DateUtc==DateTime.MaxValue)?&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
DateUtc:DateUtc.ToLocalTime(); 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; } 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font color=#0000ff size=2&gt;set&lt;/font&gt;&lt;font size=2&gt; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; { 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DateUtc = (&lt;/font&gt;&lt;font color=#0000ff size=2&gt;value&lt;/font&gt;&lt;font size=2&gt;==DateTime.MinValue||&lt;/font&gt;&lt;font color=#0000ff size=2&gt;value&lt;/font&gt;&lt;font size=2&gt;==DateTime.MaxValue)?&lt;/font&gt;&lt;font color=#0000ff size=2&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
value&lt;/font&gt;&lt;font size=2&gt;:&lt;/font&gt;&lt;font color=#0000ff size=2&gt;value&lt;/font&gt;&lt;font size=2&gt;.Date.ToUniversalTime(); 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; } 
&lt;br&gt;
}&gt;
&lt;/font&gt;&lt;/font&gt;&lt;/span&gt; 
&lt;p&gt;
&lt;span class=tx&gt;So, that's why.&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span class=tx&gt;Be aware that all of this applies to ASP.NET Web Services, too, and
if you are dealing with multiple time zones are you are using UTC normalized times
in your app, you will have to deal with this. If "server time" makes you happy, you
won't need to worry.&lt;/span&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=77bd9cef-bfeb-464c-bc72-2c849e1e8616" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,77bd9cef-bfeb-464c-bc72-2c849e1e8616.aspx</comments>
      <category>Technology/XML</category>
      <category>Technology/CLR</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=39ed85fd-bd6d-4dd9-b5e1-a56bf3847f6a</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,39ed85fd-bd6d-4dd9-b5e1-a56bf3847f6a.aspx</pingback:target>
      <dc:creator />
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,39ed85fd-bd6d-4dd9-b5e1-a56bf3847f6a.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=39ed85fd-bd6d-4dd9-b5e1-a56bf3847f6a</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <div class="Section1">
          <p class="MsoNormal" style="MARGIN-BOTTOM: 12pt">
            <span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'">DateTime issued;</span>
          </p>
          <p class="MsoNormal">
            <span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'">[XmlIgnore]<br /></span>
            <span style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Lucida Console'">public</span>
            <span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'"> DateTime
IssuedUtc 
<br />
{ <span style="COLOR: blue">get</span> { <span style="COLOR: blue">return</span> issued;
} <span style="COLOR: blue">set</span> { issued = <span style="COLOR: blue">value</span>;
} }<br /><br />
[XmlElement("issued")]<br /><span style="COLOR: blue">public</span> DateTime IssuedLocalTime 
<br />
{ <span style="COLOR: blue">get</span> { <span style="COLOR: blue">return</span> Issued.ToLocalTime();
} <span style="COLOR: blue">set</span> { Issued = <span style="COLOR: blue">value</span>.ToUniversalTime();
} }</span>
          </p>
          <p class="MsoNormal">
            <span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'">
            </span> 
</p>
          <p>
Why?
</p>
        </div>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=39ed85fd-bd6d-4dd9-b5e1-a56bf3847f6a" />
      </body>
      <title>A little XmlSerializer Quiz.</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,39ed85fd-bd6d-4dd9-b5e1-a56bf3847f6a.aspx</guid>
      <link>http://vasters.com/clemensv/2003/08/14/A+Little+XmlSerializer+Quiz.aspx</link>
      <pubDate>Thu, 14 Aug 2003 17:51:49 GMT</pubDate>
      <description>&lt;div class=Section1&gt;
&lt;p class=MsoNormal style="MARGIN-BOTTOM: 12pt"&gt;
&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'"&gt;DateTime issued;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'"&gt;[XmlIgnore]&lt;br&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Lucida Console'"&gt;public&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'"&gt; DateTime
IssuedUtc 
&lt;br&gt;
{ &lt;span style="COLOR: blue"&gt;get&lt;/span&gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; issued;
} &lt;span style="COLOR: blue"&gt;set&lt;/span&gt; { issued = &lt;span style="COLOR: blue"&gt;value&lt;/span&gt;;
} }&lt;br&gt;
&lt;br&gt;
[XmlElement("issued")]&lt;br&gt;
&lt;span style="COLOR: blue"&gt;public&lt;/span&gt; DateTime IssuedLocalTime 
&lt;br&gt;
{ &lt;span style="COLOR: blue"&gt;get&lt;/span&gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; Issued.ToLocalTime();
} &lt;span style="COLOR: blue"&gt;set&lt;/span&gt; { Issued = &lt;span style="COLOR: blue"&gt;value&lt;/span&gt;.ToUniversalTime();
} }&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'"&gt;&lt;/span&gt;&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
Why?
&lt;/p&gt;
&lt;/div&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=39ed85fd-bd6d-4dd9-b5e1-a56bf3847f6a" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,39ed85fd-bd6d-4dd9-b5e1-a56bf3847f6a.aspx</comments>
      <category>Technology/XML</category>
      <category>Technology/CLR</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=af4f5b5c-cce5-4a66-bf57-6ec01c5cc17c</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,af4f5b5c-cce5-4a66-bf57-6ec01c5cc17c.aspx</pingback:target>
      <dc:creator />
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,af4f5b5c-cce5-4a66-bf57-6ec01c5cc17c.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=af4f5b5c-cce5-4a66-bf57-6ec01c5cc17c</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Dan Farino, who wrote the CLR based, Regex extended stored procedure on which I
put a <a href="http://staff.newtelligence.net/clemensv/PermaLink.aspx?guid=4384d23c-eb50-48f8-92ba-93718d842062">warning
sign</a> yesterday, wrote me an email back (I notified him that I wrote
that blog entry) and told me that he just <a href="http://www.codeproject.com/database/xp_pcre.asp?target=xp%5Fpcre">uploaded
an unmanaged version</a>. Haven't downloaded it, yet, but it seems to be
functionally equivalent. If it's stable and quick, I can think of 2 bazillon
uses for this -- including, of course, Regex based XML parsing inside SQL Server
(while we wait for Yukon). 
</p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=af4f5b5c-cce5-4a66-bf57-6ec01c5cc17c" />
      </body>
      <title>Regular expressions for SQL Server, 2nd try</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,af4f5b5c-cce5-4a66-bf57-6ec01c5cc17c.aspx</guid>
      <link>http://vasters.com/clemensv/2003/08/11/Regular+Expressions+For+SQL+Server+2nd+Try.aspx</link>
      <pubDate>Mon, 11 Aug 2003 03:55:15 GMT</pubDate>
      <description>&lt;p&gt;
Dan Farino, who wrote the CLR based, Regex extended stored procedure&amp;nbsp;on which&amp;nbsp;I
put a &lt;a href="http://staff.newtelligence.net/clemensv/PermaLink.aspx?guid=4384d23c-eb50-48f8-92ba-93718d842062"&gt;warning
sign&lt;/a&gt;&amp;nbsp;yesterday, wrote&amp;nbsp;me an email back (I notified him that I wrote
that blog entry) and&amp;nbsp;told me&amp;nbsp;that he just &lt;a href="http://www.codeproject.com/database/xp_pcre.asp?target=xp%5Fpcre"&gt;uploaded
an unmanaged version&lt;/a&gt;.&amp;nbsp;Haven't&amp;nbsp;downloaded it, yet, but it seems to be
functionally equivalent.&amp;nbsp;If it's&amp;nbsp;stable and quick, I can think of 2 bazillon
uses for this -- including, of course,&amp;nbsp;Regex based XML parsing inside SQL Server
(while we wait for Yukon). 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=af4f5b5c-cce5-4a66-bf57-6ec01c5cc17c" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,af4f5b5c-cce5-4a66-bf57-6ec01c5cc17c.aspx</comments>
      <category>Technology/CLR</category>
      <category>Technology</category>
      <category>Technology/XML</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=4384d23c-eb50-48f8-92ba-93718d842062</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,4384d23c-eb50-48f8-92ba-93718d842062.aspx</pingback:target>
      <dc:creator />
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,4384d23c-eb50-48f8-92ba-93718d842062.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=4384d23c-eb50-48f8-92ba-93718d842062</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I guess my next little toy project will be around aggregation. Not that I won't
continue adding stuff to "dasBlog", but I am quite happy with the status as of now
and once we've got Stephen's caching work in the project, we'll make it a 1.2 .
</p>
        <p>
So, the other bigger chunk of code that I have sitting around here from the blogging
infrastructure that I wrote but didn't get done in the first quarter of this year
(and from which the rendering engine made it into dasBlog) is a pretty serious,
extensible syndication engine based on Enterprise Services and SQL Server. Pulling
in RSS feeds is, in my view, a background server task. A common infrastructure
for subscribing, queuing, requesting, transforming, filtering, caching and pushing
out results (via LCE) is something that could be very handy, makes a great demo and
there's lots of sample data to gather in a short time ;)
</p>
        <p>
I am not at all interested in writing yet another aggregation GUI. I may grab one
of the available aggregators like SharpReader or RSS Bandit and hook it up for demo
purposes, but that's about it.
</p>
        <p>
So ... while looking around for tools I could use, I found this <a href="http://databasepronews.com/articles/0220df.html">cool
extended stored procedure</a> for using .NET Framework regular expressions straight
from within SQL Server. <strong><font color="red">Hold!</font></strong> What I also
found (and I actually looked for it) was this <a href="http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q322884">Microsoft
KB article</a> (Q322884) that states that extended stored procs written in managed
code "is not supported". 
</p>
        <p>
Based on some discussions I had with members of the SQL team about the
next release of SQL Server (Yukon) earlier this year about their work
around incorporating the CLR (the fact that they're doing that <a href="http://www.microsoft.com/sql/evaluation/yukon.asp">is
public</a> so I am not violating any of the papers I signed), this absolutely doesn't
come as a surprise to me and the bottom line is: This stored procedure looks cool,
but shouldn't get near a SQL Server 2000 production server, ever.
</p>
        <p>
The reason for that is that SQL Server is essentially an operating system by itself.
It does its own memory management, can do its own thread scheduling (it makes use
of  fibers, which are self-scheduled threads) and has, of course, its own I/O
system sitting on low-level OS functions. The CLR doesn't know about any of that
and SQL Server 2000 doesn't know about the CLR. If you are writing a stored procedure
in unmanaged C/C++, you create just a DLL that runs on top of Win32 and if you
follow a couple of <a href="http://support.microsoft.com/default.aspx?scid=http://support.microsoft.com:80/support/kb/articles/q190/9/87.asp&amp;NoWebContent=1">rules</a>,
you should be ok. If you are writing in C# or VB.NET, you are bringing along an environment
that doesn't know anything about these rules around SQL's use of threading and thread
local storage, probably wants to launch additional threads under the covers and whose
garbage collector hasn't been designed to cooperate with SQL's memory management.
Yes, it may run, but what happens under stress or low memory conditions? How
does it affect transactions? What's the story around performance once the CLR is present
in the process and is probably used in only one of 500 queries?  I know that
putting the CLR into Yukon is nothing that a someone at Microsoft does in
a day or two and therefore I doubt that putting the CLR into SQL 2000 within
half a day is a good idea for a real system. Things are different if you are running
inside what essentially is an OS kernel.
</p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=4384d23c-eb50-48f8-92ba-93718d842062" />
      </body>
      <title>Next steps and why some cool things are just cool at first sight, sigh!</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,4384d23c-eb50-48f8-92ba-93718d842062.aspx</guid>
      <link>http://vasters.com/clemensv/2003/08/10/Next+Steps+And+Why+Some+Cool+Things+Are+Just+Cool+At+First+Sight+Sigh.aspx</link>
      <pubDate>Sun, 10 Aug 2003 17:07:46 GMT</pubDate>
      <description>&lt;p&gt;
I guess&amp;nbsp;my next little toy project will be around aggregation. Not that I won't
continue adding stuff to "dasBlog", but I am quite happy with the status as of now
and once we've got Stephen's caching work in the project, we'll make it a 1.2&amp;nbsp;.
&lt;/p&gt;
&lt;p&gt;
So, the other bigger chunk of code that I have sitting around here from the blogging
infrastructure that I wrote but didn't get done in the first quarter of this year
(and from which the rendering engine made it into dasBlog) is a&amp;nbsp;pretty&amp;nbsp;serious,
extensible&amp;nbsp;syndication engine based on Enterprise Services and SQL Server.&amp;nbsp;Pulling
in RSS feeds is, in my view,&amp;nbsp;a background server task. A common infrastructure
for subscribing, queuing, requesting, transforming, filtering, caching&amp;nbsp;and pushing
out results (via LCE) is something that could be very handy, makes a great demo and
there's lots of sample data to gather in a short time ;)
&lt;/p&gt;
&lt;p&gt;
I am not at all interested in writing yet another aggregation GUI. I may grab one
of the available aggregators like SharpReader or RSS Bandit and hook it up for demo
purposes, but that's about it.
&lt;/p&gt;
&lt;p&gt;
So ... while looking around for tools I could use, I found this&amp;nbsp;&lt;a href="http://databasepronews.com/articles/0220df.html"&gt;cool
extended stored procedure&lt;/a&gt; for using .NET Framework regular expressions straight
from within SQL Server. &lt;strong&gt;&lt;font color=red&gt;Hold!&lt;/font&gt;&lt;/strong&gt; What I also
found (and I actually looked for it) was this &lt;a href="http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q322884"&gt;Microsoft
KB article&lt;/a&gt;&amp;nbsp;(Q322884) that states that extended stored procs written in managed
code&amp;nbsp;"is not supported".&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
Based on some discussions I had with&amp;nbsp;members of&amp;nbsp;the SQL team about&amp;nbsp;the
next&amp;nbsp;release of SQL Server (Yukon) earlier this year&amp;nbsp;about their&amp;nbsp;work
around incorporating the CLR (the fact that they're doing that&amp;nbsp;&lt;a href="http://www.microsoft.com/sql/evaluation/yukon.asp"&gt;is
public&lt;/a&gt; so I am not violating any of the papers I signed), this absolutely doesn't
come as a surprise to me and the&amp;nbsp;bottom line is: This stored procedure looks&amp;nbsp;cool,
but shouldn't get near a SQL Server 2000 production server, ever.
&lt;/p&gt;
&lt;p&gt;
The reason for that is that SQL Server is essentially an operating system by itself.
It does its own memory management, can do its own thread scheduling (it makes use
of&amp;nbsp; fibers, which are self-scheduled threads) and has, of course, its own&amp;nbsp;I/O
system sitting on low-level&amp;nbsp;OS functions. The CLR doesn't know about any of that
and SQL Server 2000 doesn't know about the CLR. If you are writing a stored procedure
in&amp;nbsp;unmanaged C/C++, you create just a DLL that runs on top of Win32 and if you
follow a couple of &lt;a href="http://support.microsoft.com/default.aspx?scid=http://support.microsoft.com:80/support/kb/articles/q190/9/87.asp&amp;amp;NoWebContent=1"&gt;rules&lt;/a&gt;,
you should be ok. If you are writing in C# or VB.NET, you are bringing along an environment
that doesn't know anything about these rules around SQL's use of threading and thread
local storage, probably wants to launch additional threads under the covers and whose
garbage collector hasn't been designed to cooperate with SQL's memory management.
Yes, it may run, but what happens under stress or&amp;nbsp;low memory conditions? How
does it affect transactions? What's the story around performance once the CLR is present
in the process and is probably used in only one of 500 queries?&amp;nbsp; I know that
putting the CLR into Yukon is nothing that a&amp;nbsp;someone at&amp;nbsp;Microsoft does in
a day or two and&amp;nbsp;therefore I doubt&amp;nbsp;that putting the CLR into SQL 2000 within
half a day is a good idea for a real system. Things are different if you are running
inside&amp;nbsp;what essentially is an&amp;nbsp;OS kernel.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=4384d23c-eb50-48f8-92ba-93718d842062" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,4384d23c-eb50-48f8-92ba-93718d842062.aspx</comments>
      <category>Technology/CLR</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=2e7e664c-7ee4-47f6-aa50-efb756cbd3f2</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,2e7e664c-7ee4-47f6-aa50-efb756cbd3f2.aspx</pingback:target>
      <dc:creator />
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,2e7e664c-7ee4-47f6-aa50-efb756cbd3f2.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=2e7e664c-7ee4-47f6-aa50-efb756cbd3f2</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <div class="Section1">
          <p>
No, I haven’t built the stuff 3219 times. It’s “3” for 2003 and “219” is today’s day
of the year. Here’s the compiled one-liner that sits in my system32 directory and
tells me …
</p>
          <p>
 
</p>
        </div>
        <p>
Download: <a href="http://staff.newtelligence.net/clemensv/content/binary/buildday.zip">buildday.zip</a><br /></p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=2e7e664c-7ee4-47f6-aa50-efb756cbd3f2" />
      </body>
      <title>Why 3219?</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,2e7e664c-7ee4-47f6-aa50-efb756cbd3f2.aspx</guid>
      <link>http://vasters.com/clemensv/2003/08/07/Why+3219.aspx</link>
      <pubDate>Thu, 07 Aug 2003 20:19:51 GMT</pubDate>
      <description>&lt;div class=Section1&gt;
&lt;p&gt;
No, I haven’t built the stuff 3219 times. It’s “3” for 2003 and “219” is today’s day
of the year. Here’s the compiled one-liner that sits in my system32 directory and
tells me …
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
Download: &lt;a href="http://staff.newtelligence.net/clemensv/content/binary/buildday.zip"&gt;buildday.zip&lt;/a&gt;
&lt;br&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=2e7e664c-7ee4-47f6-aa50-efb756cbd3f2" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,2e7e664c-7ee4-47f6-aa50-efb756cbd3f2.aspx</comments>
      <category>Technology/CLR</category>
      <category>newtelligence/dasBlog</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=d282b1f2-806f-45cb-ac83-187b86df57bc</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,d282b1f2-806f-45cb-ac83-187b86df57bc.aspx</pingback:target>
      <dc:creator />
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,d282b1f2-806f-45cb-ac83-187b86df57bc.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=d282b1f2-806f-45cb-ac83-187b86df57bc</wfw:commentRss>
      <slash:comments>4</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://www.ingorammer.com/weblog/archives/001309.html">Ingo says</a> that
"sealed" classes are a good thing and goes great lengths to explain why he thinks
so in <a href="http://www.ingorammer.com/Articles/SealedIsGood.html">this article.</a></p>
        <p>
Now, I do have a little problem with his conclusion (which I still partially share,
because I do write sealed classes every once in a while, but for a slightly different
reason, see below) because the example he's using isn't really fitting the
problem and he actually makes some assumptions about the ImageList class that aren't
accurate in this context. 
</p>
        <p>
First off, the property ImageList.Images isn't virtual and therefore cannot be overridden,
at all. So that by itself is no reason to make the class sealed. The property has
been introduced by the class, the class designer chose not to make it virtual. Can't
be overriden, done. The same is true for all other properties except <em>Container</em> and <em>Site, </em>which
are inherited from System.ComponentModel.Component. I fail to see anything on the
ImageList class (not even a method) that really justifies the lockup using <em>sealed </em>considering
the current version of the Framework. The bad that <em>sealed</em> does
here is that I can't create a wrapper around the ImageList that simplifies setting
up such a list in my specific environment.
</p>
        <p>
Using <em>sealed</em> on a class is a very brutal thing to do. A more gentle way of
using the sealed keyword is to say [<em>void sealed override myMethod() { }</em>],
which essentially says: "Within my own class space I am using inheritance for this
method, but since outsiders don't know what I am doing I won't let them
override the behavior from here downwards in the class hierarchy." That doesn't affect
the inheritability of the entire class and hence doesn't adversely affect the
ability to wrap the existing functionality. 
</p>
        <p>
Now ... is <em>sealed</em> on a class just plain evil? There are two answers:
</p>
        <ul>
          <li>
Yes. The keyword <em>sealed</em> on a class usually doesn't have much or any of a
technical justification in the "here and now" version of a class library. 
</li>
          <li>
No. The keyword <em>sealed</em> conveys a very clear message that the
class designer reserves the right to change the class so dramatically in a future
release of the product that you would be tremendously unhappy if you had derived
from it to implement your own functionality, once that new version comes along. <em>Sealed</em> says:
This is going to change in a big way.</li>
        </ul>
        <p>
 
</p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=d282b1f2-806f-45cb-ac83-187b86df57bc" />
      </body>
      <title>Ingo says that "sealed" is good. Is it?</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,d282b1f2-806f-45cb-ac83-187b86df57bc.aspx</guid>
      <link>http://vasters.com/clemensv/2003/07/24/Ingo+Says+That+Sealed+Is+Good+Is+It.aspx</link>
      <pubDate>Thu, 24 Jul 2003 14:49:31 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="http://www.ingorammer.com/weblog/archives/001309.html"&gt;Ingo says&lt;/a&gt; that
"sealed" classes are a good thing and goes great lengths to explain why he thinks
so in &lt;a href="http://www.ingorammer.com/Articles/SealedIsGood.html"&gt;this article.&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
Now, I do have a little problem with his conclusion (which I still partially share,
because I do write sealed classes every once in a while, but for a slightly different
reason, see below) because&amp;nbsp;the example he's using isn't&amp;nbsp;really fitting&amp;nbsp;the
problem and he actually makes some assumptions about the ImageList class that aren't
accurate in this context.&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
First off, the property ImageList.Images isn't virtual and therefore cannot be overridden,
at all. So that by itself is no reason to make the class sealed. The property has
been introduced by the class, the class designer chose not to make it virtual. Can't
be overriden, done. The same is true for all other properties except&amp;nbsp;&lt;em&gt;Container&lt;/em&gt; and &lt;em&gt;Site, &lt;/em&gt;which
are inherited from System.ComponentModel.Component. I fail to see anything on the
ImageList class&amp;nbsp;(not even a method) that really justifies the lockup using &lt;em&gt;sealed&amp;nbsp;&lt;/em&gt;considering
the current version of the Framework.&amp;nbsp;The bad that&amp;nbsp;&lt;em&gt;sealed&lt;/em&gt; does
here is that I can't create a wrapper around the ImageList that simplifies setting
up such a list in my specific environment.
&lt;/p&gt;
&lt;p&gt;
Using &lt;em&gt;sealed&lt;/em&gt; on a class is a very brutal thing to do. A more gentle way of
using the sealed keyword is to say [&lt;em&gt;void sealed override myMethod() { }&lt;/em&gt;],
which essentially says: "Within my own class space I am using inheritance for this
method, but since&amp;nbsp;outsiders don't know what I am doing I won't let&amp;nbsp;them
override the behavior from here downwards in the class hierarchy." That doesn't affect
the inheritability of the entire class and hence doesn't&amp;nbsp;adversely affect the
ability to&amp;nbsp;wrap the existing functionality.&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
Now ... is &lt;em&gt;sealed&lt;/em&gt; on a class just plain evil?&amp;nbsp;There are&amp;nbsp;two answers:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Yes. The keyword &lt;em&gt;sealed&lt;/em&gt; on a class usually doesn't have much or any of a
technical&amp;nbsp;justification in the "here and now" version of a class library. 
&lt;li&gt;
No. The keyword &lt;em&gt;sealed&lt;/em&gt;&amp;nbsp;conveys&amp;nbsp;a very&amp;nbsp;clear message that the
class designer reserves the right to change the class so dramatically in a future
release of the product that you would be&amp;nbsp;tremendously unhappy if you had derived
from it to implement your own functionality, once that new version comes along. &lt;em&gt;Sealed&lt;/em&gt; says:
This is going to change in a big way.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=d282b1f2-806f-45cb-ac83-187b86df57bc" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,d282b1f2-806f-45cb-ac83-187b86df57bc.aspx</comments>
      <category>Technology/CLR</category>
    </item>
    <item>
      <trackback:ping>http://vasters.com/clemensv/Trackback.aspx?guid=220</trackback:ping>
      <pingback:server>http://vasters.com/clemensv/pingback.aspx</pingback:server>
      <pingback:target>http://vasters.com/clemensv/PermaLink,guid,220.aspx</pingback:target>
      <dc:creator />
      <wfw:comment>http://vasters.com/clemensv/CommentView,guid,220.aspx</wfw:comment>
      <wfw:commentRss>http://vasters.com/clemensv/SyndicationService.asmx/GetEntryCommentsRss?guid=220</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <strong>Quake II on .NET.</strong> Scott Stanfield and his team at Vertigo Software show
yet another nice trick: <a href="http://www.vertigosoftware.com/quake2">Quake II in
managed code</a>.
</p>
        <img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=220" />
      </body>
      <title>Quake II on .NET</title>
      <guid isPermaLink="false">http://vasters.com/clemensv/PermaLink,guid,220.aspx</guid>
      <link>http://vasters.com/clemensv/2003/07/11/Quake+II+On+NET.aspx</link>
      <pubDate>Fri, 11 Jul 2003 09:07:09 GMT</pubDate>
      <description>&lt;p&gt;
&lt;strong&gt;Quake II on .NET.&lt;/strong&gt; Scott Stanfield and his team at Vertigo Software&amp;nbsp;show
yet another nice trick: &lt;a href="http://www.vertigosoftware.com/quake2"&gt;Quake II in
managed code&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vasters.com/clemensv/aggbug.ashx?id=220" /&gt;</description>
      <comments>http://vasters.com/clemensv/CommentView,guid,220.aspx</comments>
      <category>Technology/CLR</category>
    </item>
  </channel>
</rss>