<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.charteris.com/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title type="html">Chris Dickson&amp;#39;s Blog</title><subtitle type="html" /><id>http://blogs.charteris.com/blogs/chrisdi/atom.aspx</id><link rel="alternate" type="text/html" href="http://blogs.charteris.com/blogs/chrisdi/default.aspx" /><link rel="self" type="application/atom+xml" href="http://blogs.charteris.com/blogs/chrisdi/atom.aspx" /><generator uri="http://communityserver.org" version="3.0.20611.960">Community Server</generator><updated>2006-10-31T11:41:38Z</updated><entry><title>Exploring the WCF Named Pipe Binding - Part 3</title><link rel="alternate" type="text/html" href="http://blogs.charteris.com/blogs/chrisdi/archive/2008/06/23/exploring-the-wcf-named-pipe-binding-part-3.aspx" /><id>http://blogs.charteris.com/blogs/chrisdi/archive/2008/06/23/exploring-the-wcf-named-pipe-binding-part-3.aspx</id><published>2008-06-23T13:08:12Z</published><updated>2008-06-23T13:08:12Z</updated><content type="html">&lt;p&gt;In this post I will show&amp;nbsp;one way to restrict access to the named pipe created by the WCF named pipe listener, to provide a partial workaround for the security flaw mentioned in my last post.&lt;/p&gt; &lt;p&gt;The strategy is to target directly the internal property AllowedUsers on the type System.ServiceModel.Channels.NamedPipeChannelListener. We cannot call this property normally because it is internal to WCF, but reflection allows an alternative way to invoke it. Since this only needs to be done once, when Open is called on the&amp;nbsp;ServiceHost&amp;nbsp;to build the service run-time, the performance cost of using reflection is not an issue here. We will populate this AllowedUsers collection with the SID for a Group representing the authorised users of the service we are protecting, supplied as a parameter of the binding before the service is opened. It turns out we also need to add the SID for the service account itself, for reasons I will explain in more detail below. WCF will then use this collection of SIDs, rather than its default list (EVERYONE), when calling CreateNamedPipe in the PipeConnectionListener.&lt;/p&gt; &lt;p&gt;After Open has been called on the ServiceHost, WCF builds the server run-time stack. The key part of this process which interests us is the point where the channel listener is created by the transport binding element. When using the standard netNamedPipe binding, the relevant transport binding element is of type System.ServiceModel.NamedPipeTransportBindingElement. We can conveniently perform our amendment to the configuration of the listener, by subclassing this NamedPipeTransportBindingElement and overriding the virtual method BuildChannelListener&amp;lt;&amp;gt;(). This allows us to get a reference to the listener after it has been created by the standard WCF transport binding element code, but before BeginAccept() is called on it (whch is when the first&amp;nbsp;pipe instance is created).&lt;/p&gt; &lt;p&gt;Here is some code for a custom named pipe binding which implements this strategy:&lt;/p&gt; &lt;div style="border-right:black 1px solid;padding-right:10px;border-top:black 1px solid;padding-left:10px;padding-bottom:10px;margin:0px auto;border-left:black 1px solid;width:95%;padding-top:10px;border-bottom:black 1px solid;text-align:left;"&gt; &lt;p&gt;&lt;font size="2"&gt;&lt;font color="#0000ff"&gt;&lt;font face="Courier New"&gt;using&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt; System;&lt;/font&gt;&lt;br /&gt;&lt;font color="#0000ff"&gt;&lt;font face="Courier New"&gt;using&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt; System.Collections.Generic;&lt;/font&gt;&lt;br /&gt;&lt;font color="#0000ff"&gt;&lt;font face="Courier New"&gt;using&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt; System.ServiceModel.Channels;&lt;/font&gt;&lt;br /&gt;&lt;font color="#0000ff"&gt;&lt;font face="Courier New"&gt;using&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt; System.ServiceModel;&lt;/font&gt;&lt;br /&gt;&lt;font color="#0000ff"&gt;&lt;font face="Courier New"&gt;using&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt; System.Reflection;&lt;/font&gt;&lt;br /&gt;&lt;font color="#0000ff"&gt;&lt;font face="Courier New"&gt;using&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt; System.Security.Principal;&lt;/font&gt;&lt;br /&gt;&lt;font color="#0000ff"&gt;&lt;font face="Courier New"&gt;using&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt; System.Threading;&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;&lt;font color="#0000ff"&gt; &lt;p&gt;&lt;font face="Courier New" size="2"&gt;namespace&lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt; Charteris.ChrisDicksonBlog.Samples&lt;/font&gt;&lt;br /&gt;&lt;font face="Courier New"&gt;{&lt;/font&gt;&lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font size="2"&gt;&lt;font color="#0000ff"&gt;&amp;nbsp; public&lt;/font&gt; &lt;font color="#0000ff"&gt;class&lt;/font&gt; &lt;font color="#008080"&gt;AclSecuredNamedPipeBinding&lt;/font&gt; : &lt;/font&gt;&lt;font color="#008080" size="2"&gt;CustomBinding&lt;br /&gt;&amp;nbsp; &lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;{&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public&lt;/font&gt; AclSecuredNamedPipeBinding()&lt;/font&gt;&lt;font face="Courier New"&gt;: &lt;font color="#0000ff"&gt;base&lt;/font&gt;()&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font face="Courier New"&gt;{&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font face="Courier New"&gt;&lt;font color="#008080"&gt;NetNamedPipeBinding&lt;/font&gt; standardBinding = &lt;font color="#0000ff"&gt;new&lt;/font&gt; &lt;font color="#008080"&gt;NetNamedPipeBinding&lt;/font&gt;(&lt;font color="#008080"&gt;NetNamedPipeSecurityMode&lt;/font&gt;.Transport);&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;foreach&lt;/font&gt; (&lt;font color="#008080"&gt;BindingElement&lt;/font&gt; element &lt;font color="#0000ff"&gt;in&lt;/font&gt; standardBinding.CreateBindingElements())&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font face="Courier New"&gt;{&lt;/font&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; &lt;font face="Courier New"&gt;&lt;font color="#008080"&gt;NamedPipeTransportBindingElement&lt;/font&gt; transportElement = element &lt;font color="#0000ff"&gt;as&lt;/font&gt; &lt;font color="#008080"&gt;NamedPipeTransportBindingElement&lt;/font&gt;;&lt;/font&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; &lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;base&lt;/font&gt;.Elements.Add(&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; &lt;font color="#0000ff"&gt;null&lt;/font&gt; != transportElement ? &lt;font color="#0000ff"&gt;new&lt;/font&gt; &lt;font color="#008080"&gt;AclSecuredNamedPipeTransportBindingElement&lt;/font&gt;(transportElement) : element);&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font face="Courier New"&gt;}&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font face="Courier New"&gt;AddUserOrGroup(&lt;font color="#008080"&gt;WindowsIdentity&lt;/font&gt;.GetCurrent().User);&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font face="Courier New"&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public&lt;/font&gt; &lt;font color="#0000ff"&gt;void&lt;/font&gt; AddUserOrGroup(&lt;font color="#008080"&gt;SecurityIdentifier&lt;/font&gt; sid)&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font face="Courier New"&gt;{&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font face="Courier New"&gt;&lt;font color="#008080"&gt;List&lt;/font&gt;&amp;lt;&lt;font color="#008080"&gt;SecurityIdentifier&lt;/font&gt;&amp;gt; allowedUsers &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; = Elements.Find&amp;lt;&lt;font color="#008080"&gt;AclSecuredNamedPipeTransportBindingElement&lt;/font&gt;&amp;gt;().AllowedUsers;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;if&lt;/font&gt; (!allowedUsers.Contains(sid))&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font face="Courier New"&gt;{&lt;/font&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; &lt;font face="Courier New"&gt;allowedUsers.Add(sid);&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font face="Courier New"&gt;}&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font face="Courier New"&gt;}&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;font face="Courier New"&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&lt;font size="2"&gt;&lt;font color="#0000ff"&gt;&amp;nbsp; public&lt;/font&gt; &lt;font color="#0000ff"&gt;class&lt;/font&gt; &lt;font color="#008080"&gt;AclSecuredNamedPipeTransportBindingElement&lt;/font&gt; : &lt;/font&gt;&lt;font color="#008080" size="2"&gt;NamedPipeTransportBindingElement&lt;br /&gt;&amp;nbsp; &lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;{&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font size="2"&gt;&lt;font color="#0000ff"&gt;private&lt;/font&gt; &lt;font color="#0000ff"&gt;static&lt;/font&gt; &lt;font color="#008080"&gt;Type&lt;/font&gt; namedPipeChannelListenerType&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;= &lt;font color="#008080"&gt;Type&lt;/font&gt;.GetType(&lt;font color="#800000"&gt;&amp;quot;System.ServiceModel.Channels.NamedPipeChannelListener, System.ServiceModel&amp;quot;&lt;/font&gt;, &lt;font color="#0000ff"&gt;false&lt;/font&gt;);&lt;/font&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public&lt;/font&gt; AclSecuredNamedPipeTransportBindingElement(&lt;font color="#008080"&gt;NamedPipeTransportBindingElement&lt;/font&gt; inner)&lt;/font&gt;&lt;font face="Courier New"&gt;: &lt;font color="#0000ff"&gt;base&lt;/font&gt;(inner)&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;{&lt;br /&gt;&lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;if&lt;/font&gt; (inner &lt;font color="#0000ff"&gt;is&lt;/font&gt; &lt;font color="#008080"&gt;AclSecuredNamedPipeTransportBindingElement&lt;/font&gt;)&lt;br /&gt;&lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font face="Courier New"&gt;{&lt;/font&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;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;_allowedUsers = &lt;font color="#0000ff"&gt;new&lt;/font&gt; &lt;font color="#008080"&gt;List&lt;/font&gt;&amp;lt;&lt;font color="#008080"&gt;SecurityIdentifier&lt;/font&gt;&amp;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;((&lt;font color="#008080"&gt;AclSecuredNamedPipeTransportBindingElement&lt;/font&gt;)inner)._allowedUsers);&lt;br /&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public&lt;/font&gt; &lt;font color="#0000ff"&gt;override&lt;/font&gt; &lt;font color="#008080"&gt;BindingElement&lt;/font&gt; Clone()&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font face="Courier New"&gt;{&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;return&lt;/font&gt; &lt;font color="#0000ff"&gt;new&lt;/font&gt; &lt;font color="#008080"&gt;AclSecuredNamedPipeTransportBindingElement&lt;/font&gt;(&lt;font color="#0000ff"&gt;this&lt;/font&gt;);&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font face="Courier New"&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public&lt;/font&gt; &lt;font color="#0000ff"&gt;override&lt;/font&gt; &lt;font color="#008080"&gt;IChannelListener&lt;/font&gt;&amp;lt;TChannel&amp;gt; BuildChannelListener&amp;lt;TChannel&amp;gt;(&lt;font color="#008080"&gt;BindingContext&lt;/font&gt; context)&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font face="Courier New" size="2"&gt;{&lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font size="2"&gt;&lt;font color="#008080"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;IChannelListener&lt;/font&gt;&amp;lt;TChannel&amp;gt; listener = &lt;font color="#0000ff"&gt;base&lt;/font&gt;.BuildChannelListener&amp;lt;TChannel&amp;gt;(context);&lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font size="2"&gt;&lt;font color="#008080"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PropertyInfo&lt;/font&gt; p = namedPipeChannelListenerType.GetProperty(&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;&lt;font color="#800000"&gt;&amp;quot;AllowedUsers&amp;quot;&lt;/font&gt;, &lt;font color="#008080"&gt;BindingFlags&lt;/font&gt;.Instance|&lt;font color="#008080"&gt;BindingFlags&lt;/font&gt;.NonPublic);&lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; p.SetValue(listener, _allowedUsers, &lt;font color="#0000ff"&gt;null&lt;/font&gt;);&lt;br /&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return&lt;/font&gt; listener;&lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/font&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&lt;font size="2"&gt;&lt;font color="#0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; internal&lt;/font&gt; &lt;font color="#008080"&gt;List&lt;/font&gt;&amp;lt;&lt;font color="#008080"&gt;SecurityIdentifier&lt;/font&gt;&amp;gt; AllowedUsers { &lt;font color="#0000ff"&gt;get&lt;/font&gt; { &lt;font color="#0000ff"&gt;return&lt;/font&gt; _allowedUsers; } }&lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font size="2"&gt;&lt;font color="#0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private&lt;/font&gt; &lt;font color="#008080"&gt;List&lt;/font&gt;&amp;lt;&lt;font color="#008080"&gt;SecurityIdentifier&lt;/font&gt;&amp;gt; _allowedUsers = &lt;font color="#0000ff"&gt;new&lt;/font&gt; &lt;font color="#008080"&gt;List&lt;/font&gt;&amp;lt;&lt;font color="#008080"&gt;SecurityIdentifier&lt;/font&gt;&amp;gt;();&lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&amp;nbsp; }&lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;}&lt;/font&gt;&lt;/font&gt;&amp;nbsp;&lt;/p&gt;&lt;/div&gt; &lt;p&gt;As it stands, this code allows the SIDs of service users to be added in code but not by means of service configuration. The latter is left as an exercise for the reader, as they say.&lt;/p&gt; &lt;p&gt;Using this custom binding, we can&amp;nbsp;restrict use of a service endpoint to members of a specific Windows group, by means of code like this in the service host:&lt;/p&gt; &lt;div style="border-right:black 1px solid;padding-right:10px;border-top:black 1px solid;padding-left:10px;padding-bottom:10px;margin:0px auto;border-left:black 1px solid;width:95%;padding-top:10px;border-bottom:black 1px solid;text-align:left;"&gt; &lt;p&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;font color="#008080"&gt;AclSecuredNamedPipeBinding&lt;/font&gt; binding = &lt;font color="#0000ff"&gt;new&lt;/font&gt; &lt;font color="#008080"&gt;AclSecuredNamedPipeBinding&lt;/font&gt;();&lt;/font&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;font color="#008080"&gt;SecurityIdentifier&lt;/font&gt; allowedGroup &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = (&lt;font color="#008080"&gt;SecurityIdentifier&lt;/font&gt;)(&lt;font color="#0000ff"&gt;new&lt;/font&gt; &lt;font color="#008080"&gt;NTAccount&lt;/font&gt;(&lt;font color="#800000"&gt;&amp;quot;NPServiceUsers&amp;quot;&lt;/font&gt;).Translate(&lt;font color="#0000ff"&gt;typeof&lt;/font&gt;(&lt;font color="#008080"&gt;SecurityIdentifier&lt;/font&gt;)));&lt;/font&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New" size="2"&gt;binding.AddUserOrGroup(allowedGroup);&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New" size="2"&gt;...&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New" size="2"&gt;_serviceHost.AddServiceEndpoint(&lt;font color="#0000ff"&gt;... &lt;/font&gt;, binding, ...);&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New" size="2"&gt;...&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New" size="2"&gt;_serviceHost.Open()&lt;/font&gt;&lt;/p&gt;&lt;/div&gt; &lt;p&gt;I described this as a partial workaround for the flaw in the default security provided by the standard binding. It is not a full workaround because SIDs which are allowed access to the pipe still have the powerful permission FILE_CREATE_PIPE_INSTANCE, which ideally we would not want anyone other then the service account itself to have.&lt;/p&gt; &lt;p&gt;I said I would say something about why we need to add the service account itself to the AllowedUsers collection. This&amp;nbsp;relates back&amp;nbsp;to the CREATOR OWNER anomaly in the pipe DACL, which I raised in my last post. You might think (and I suspect one of the WCF developers thought) that this ACE in the DACL would grant the service account the rights it needs to set up the listener and handle client requests arriving on the pipe. This isn&amp;#39;t the case, though... it is actually the EVERYONE ACE which enables a service using the&amp;nbsp;standard binding to work correctly.&lt;/p&gt; &lt;p&gt;Let&amp;#39;s look what happens if we remove the line &lt;/p&gt; &lt;p&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font face="Courier New"&gt;AddUserOrGroup(&lt;font color="#008080"&gt;WindowsIdentity&lt;/font&gt;.GetCurrent().User);&lt;/font&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;from the constructor&amp;nbsp;the custom binding, so that the DACL on the pipe just contains the NETWORK deny ACE, an ACE allowing access to our service users&amp;#39; group, and the CREATOR OWNER ACE. In other words, just like the one created by the standard binding, except with our service users&amp;#39; group instead of EVERYONE.&amp;nbsp; &lt;/p&gt; &lt;p&gt;With this configuration,&amp;nbsp;the service appears to start correctly, but as soon as the first client message hits the pipe,&amp;nbsp;the service host starts to consume CPU cycles uncontrollably (and ultimately has to be killed) and the client never gets any response.&amp;nbsp;Turning on tracing shows that the service is repeatedly trying to create a new pipe instance, and failing with an Access Denied error:&lt;/p&gt; &lt;div style="border-right:black 1px solid;padding-right:10px;border-top:black 1px solid;padding-left:10px;padding-bottom:10px;margin:0px auto;border-left:black 1px solid;width:95%;padding-top:10px;border-bottom:black 1px solid;text-align:left;"&gt; &lt;p&gt;&amp;lt;E2ETraceEvent xmlns=&amp;quot;&lt;a href="http://schemas.microsoft.com/2004/06/E2ETraceEvent&amp;quot;&amp;gt;&amp;lt;System"&gt;http://schemas.microsoft.com/2004/06/E2ETraceEvent&amp;quot;&amp;gt;&amp;lt;System&lt;/a&gt; xmlns=&amp;quot;&lt;a href="http://schemas.microsoft.com/2004/06/windows/eventlog/system&amp;quot;&amp;gt;&amp;lt;EventID&amp;gt;131075&amp;lt;/EventID&amp;gt;&amp;lt;Type&amp;gt;3&amp;lt;/Type&amp;gt;&amp;lt;SubType"&gt;http://schemas.microsoft.com/2004/06/windows/eventlog/system&amp;quot;&amp;gt;&amp;lt;EventID&amp;gt;131075&amp;lt;/EventID&amp;gt;&amp;lt;Type&amp;gt;3&amp;lt;/Type&amp;gt;&amp;lt;SubType&lt;/a&gt; Name=&amp;quot;Error&amp;quot;&amp;gt;0&amp;lt;/SubType&amp;gt;&amp;lt;Level&amp;gt;2&amp;lt;/Level&amp;gt;&amp;lt;TimeCreated SystemTime=&amp;quot;2008-05-14T09:47:27.8109616Z&amp;quot; /&amp;gt;&amp;lt;Source Name=&amp;quot;System.ServiceModel&amp;quot; /&amp;gt;&amp;lt;Correlation ActivityID=&amp;quot;{905d5b25-0f13-4f25-b3fb-a31d9a69738f}&amp;quot; /&amp;gt;&amp;lt;Execution ProcessName=&amp;quot;WCFDemoNPServer&amp;quot; ProcessID=&amp;quot;5916&amp;quot; ThreadID=&amp;quot;3&amp;quot; /&amp;gt;&amp;lt;Channel /&amp;gt;&amp;lt;Computer&amp;gt;#####&amp;lt;/Computer&amp;gt;&amp;lt;/System&amp;gt;&amp;lt;ApplicationData&amp;gt;&amp;lt;TraceData&amp;gt;&amp;lt;DataItem&amp;gt;&amp;lt;TraceRecord xmlns=&amp;quot;&lt;a href="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord"&gt;http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord&lt;/a&gt;&amp;quot; Severity=&amp;quot;Error&amp;quot;&amp;gt;&amp;lt;TraceIdentifier&amp;gt;http://msdn.microsoft.com/en-GB/library/System.ServiceModel.Diagnostics.ThrowingException.aspx&amp;lt;/TraceIdentifier&amp;gt;&amp;lt;Description&amp;gt;Throwing an exception.&amp;lt;/Description&amp;gt;&amp;lt;AppDomain&amp;gt;WCFDemoNPServer.exe&amp;lt;/AppDomain&amp;gt;&lt;br /&gt;&amp;lt;Exception&amp;gt;&lt;br /&gt;&amp;lt;ExceptionType&amp;gt;System.ServiceModel.AddressAccessDeniedException, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089&amp;lt;/ExceptionType&amp;gt;&lt;br /&gt;&amp;lt;Message&amp;gt;&lt;br /&gt;Cannot listen on pipe &amp;#39;net.pipe://localhost/WCFDemoNPServer/NPService&amp;#39;: Unrecognized error 5 (0x5)&lt;br /&gt;&amp;lt;/Message&amp;gt;&lt;br /&gt;&amp;lt;StackTrace&amp;gt;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp; at System.ServiceModel.Channels.PipeConnectionListener.CreatePipe()&lt;br /&gt;&amp;nbsp;&amp;nbsp; at System.ServiceModel.Channels.PipeConnectionListener.BeginAccept(AsyncCallback callback, Object state)&lt;br /&gt;&amp;nbsp;&amp;nbsp; at System.ServiceModel.Channels.BufferedConnectionListener.BeginAccept(AsyncCallback callback, Object state)&lt;br /&gt;&amp;nbsp;&amp;nbsp; at System.ServiceModel.Channels.TracingConnectionListener.BeginAccept(AsyncCallback callback, Object state)&lt;br /&gt;&amp;nbsp;&amp;nbsp; at System.ServiceModel.Channels.ConnectionAcceptor.AcceptIfNecessary(Boolean startAccepting)&lt;br /&gt;&amp;nbsp;&amp;nbsp; at System.ServiceModel.Channels.ConnectionAcceptor.HandleCompletedAccept(IAsyncResult result)&lt;br /&gt;&amp;nbsp;&amp;nbsp; at System.ServiceModel.Channels.ConnectionAcceptor.AcceptCompletedCallback(IAsyncResult result)&lt;br /&gt;&amp;nbsp;&amp;nbsp; at System.ServiceModel.Diagnostics.Utility.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)&lt;br /&gt;&amp;nbsp;&amp;nbsp; at System.ServiceModel.AsyncResult.Complete(Boolean completedSynchronously)&lt;br /&gt;&amp;nbsp;&amp;nbsp; at System.ServiceModel.Channels.PipeConnectionListener.PendingAccept.OnAcceptComplete(Boolean haveResult, Int32 error, Int32 numBytes)&lt;br /&gt;&amp;nbsp;&amp;nbsp; at System.ServiceModel.Channels.OverlappedContext.CompleteCallback(UInt32 error, UInt32 numBytes, NativeOverlapped* nativeOverlapped)&lt;br /&gt;&amp;nbsp;&amp;nbsp; at System.ServiceModel.Diagnostics.Utility.IOCompletionThunk.UnhandledExceptionFrame(UInt32 error, UInt32 bytesRead, NativeOverlapped* nativeOverlapped)&lt;br /&gt;&amp;nbsp;&amp;nbsp; at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)&lt;br /&gt;&amp;lt;/StackTrace&amp;gt;&lt;/p&gt; &lt;p&gt;&amp;lt;ExceptionString&amp;gt;System.ServiceModel.AddressAccessDeniedException: Cannot listen on pipe &amp;#39;net.pipe://localhost/WCFDemoNPServer/NPService&amp;#39;: Unrecognized error 5 (0x5) ---&amp;amp;amp;gt; System.IO.PipeException: Cannot listen on pipe &amp;#39;net.pipe://localhost/WCFDemoNPServer/NPService&amp;#39;: Unrecognized error 5 (0x5)&lt;br /&gt;&amp;nbsp;&amp;nbsp; --- End of inner exception stack trace ---&amp;lt;/ExceptionString&amp;gt;&amp;lt;InnerException&amp;gt;&amp;lt;ExceptionType&amp;gt;System.IO.PipeException, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089&amp;lt;/ExceptionType&amp;gt;&amp;lt;Message&amp;gt;Cannot listen on pipe &amp;#39;net.pipe://localhost/WCFDemoNPServer/NPService&amp;#39;: Unrecognized error 5 (0x5)&amp;lt;/Message&amp;gt;&amp;lt;StackTrace&amp;gt;&amp;nbsp;&amp;nbsp; at System.ServiceModel.Channels.PipeConnectionListener.CreatePipe()&lt;br /&gt;&amp;nbsp;&amp;nbsp; at System.ServiceModel.Channels.PipeConnectionListener.BeginAccept(AsyncCallback callback, Object state)&lt;br /&gt;&amp;nbsp;&amp;nbsp; at System.ServiceModel.Channels.BufferedConnectionListener.BeginAccept(AsyncCallback callback, Object state)&lt;br /&gt;&amp;nbsp;&amp;nbsp; at System.ServiceModel.Channels.TracingConnectionListener.BeginAccept(AsyncCallback callback, Object state)&lt;br /&gt;&amp;nbsp;&amp;nbsp; at System.ServiceModel.Channels.ConnectionAcceptor.AcceptIfNecessary(Boolean startAccepting)&lt;br /&gt;&amp;nbsp;&amp;nbsp; at System.ServiceModel.Channels.ConnectionAcceptor.HandleCompletedAccept(IAsyncResult result)&lt;br /&gt;&amp;nbsp;&amp;nbsp; at System.ServiceModel.Channels.ConnectionAcceptor.AcceptCompletedCallback(IAsyncResult result)&lt;br /&gt;&amp;nbsp;&amp;nbsp; at System.ServiceModel.Diagnostics.Utility.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)&lt;br /&gt;&amp;nbsp;&amp;nbsp; at System.ServiceModel.AsyncResult.Complete(Boolean completedSynchronously)&lt;br /&gt;&amp;nbsp;&amp;nbsp; at System.ServiceModel.Channels.PipeConnectionListener.PendingAccept.OnAcceptComplete(Boolean haveResult, Int32 error, Int32 numBytes)&lt;br /&gt;&amp;nbsp;&amp;nbsp; at System.ServiceModel.Channels.OverlappedContext.CompleteCallback(UInt32 error, UInt32 numBytes, NativeOverlapped* nativeOverlapped)&lt;br /&gt;&amp;nbsp;&amp;nbsp; at System.ServiceModel.Diagnostics.Utility.IOCompletionThunk.UnhandledExceptionFrame(UInt32 error, UInt32 bytesRead, NativeOverlapped* nativeOverlapped)&lt;br /&gt;&amp;nbsp;&amp;nbsp; at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)&lt;br /&gt;&amp;lt;/StackTrace&amp;gt;&amp;lt;ExceptionString&amp;gt;System.IO.PipeException: Cannot listen on pipe &amp;#39;net.pipe://localhost/WCFDemoNPServer/NPService&amp;#39;: Unrecognized error 5 (0x5)&amp;lt;/ExceptionString&amp;gt;&amp;lt;/InnerException&amp;gt;&lt;/p&gt; &lt;p&gt;&amp;lt;/Exception&amp;gt;&amp;lt;/TraceRecord&amp;gt;&amp;lt;/DataItem&amp;gt;&amp;lt;/TraceData&amp;gt;&amp;lt;/ApplicationData&amp;gt;&amp;lt;/E2ETraceEvent&amp;gt;&amp;nbsp;&lt;/p&gt;&lt;/div&gt; &lt;p&gt;In essence, it seems to me that what is happening is that the service succeeds in getting a handle to the first pipe instance, at the time the pipe is created, but because it hasn&amp;#39;t granted itself an ACE in the DACL on the pipe, it is locking itself out of obtaining handles to new instances of the pipe, which it needs to do as soon as a client request is received on the first instance. And there is clearly another bug in the IO completion code for the PipeConnectionListener, which causes this exception to recurse rather than faulting the service host.&lt;/p&gt; &lt;p&gt;So, we have to make the service account itself an AllowedUser, to stop this happening.&lt;/p&gt;&lt;img src="http://blogs.charteris.com/aggbug.aspx?PostID=578" width="1" height="1"&gt;</content><author><name>chrisdi</name><uri>http://blogs.charteris.com/members/chrisdi.aspx</uri></author><category term="WCF" scheme="http://blogs.charteris.com/blogs/chrisdi/archive/tags/WCF/default.aspx" /><category term="SOA" scheme="http://blogs.charteris.com/blogs/chrisdi/archive/tags/SOA/default.aspx" /><category term="Security" scheme="http://blogs.charteris.com/blogs/chrisdi/archive/tags/Security/default.aspx" /></entry><entry><title>Exploring the WCF Named Pipe Binding - Part 2</title><link rel="alternate" type="text/html" href="http://blogs.charteris.com/blogs/chrisdi/archive/2008/06/16/exploring-the-wcf-named-pipe-binding-part-2.aspx" /><id>http://blogs.charteris.com/blogs/chrisdi/archive/2008/06/16/exploring-the-wcf-named-pipe-binding-part-2.aspx</id><published>2008-06-16T18:04:14Z</published><updated>2008-06-16T18:04:14Z</updated><content type="html">&lt;p&gt;In&amp;nbsp;my previous post I explained how the named pipe for a WCF NetNamedPipe endpoint is named, and how a client discovers this name in order to connect to the service. This time, I&amp;#39;m looking at the Windows-level security.&lt;/p&gt; &lt;p&gt;Both the named pipe itself, and the shared memory object used by the server to publish the name of the pipe to clients, are objects which Windows secures with Access Control Lists (ACLs). Let&amp;#39;s look at the named pipe itself first of all...&lt;/p&gt; &lt;p&gt;The ACL&amp;nbsp;set up&amp;nbsp;when WCF creates the named pipe&amp;nbsp;looks like this in SDDL (Security Description Definition Language):&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font color="#000080"&gt;D:(D;;FA;;;NU)(A;;0x12019f;;;WD)(A;;0x12019f;;;CO)&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;The elements of this SDDL translate as follows:&lt;/p&gt; &lt;div style="border-right:black 1px solid;padding-right:10px;border-top:black 1px solid;padding-left:10px;padding-bottom:10px;margin:0px auto;border-left:black 1px solid;width:95%;padding-top:10px;border-bottom:black 1px solid;text-align:left;"&gt; &lt;p&gt;&lt;font color="#000080"&gt;(D;;FA;;;NU)&lt;/font&gt; - Deny Full Access to NETWORK USERS - that is: deny the access rights specified by the access mask GENERIC_ALL, to&amp;nbsp;any security context&amp;nbsp;having membership of the group with well-known SID S-1-5-2&lt;/p&gt; &lt;p&gt;&lt;font color="#000080"&gt;(A;;0x12019f;;;WD)&lt;/font&gt; - Allow the access rights specified by the access mask 0x0012019f, to EVERYONE (the well-known SID S-1-1-0)&lt;/p&gt; &lt;p&gt;&lt;font color="#000080"&gt;(A;;0x12019f;;;CO)&lt;/font&gt; - Allow the access rights specified by the access mask 0x0012019f, to the well-known SID S-1-3-0 (CREATOR OWNER)&lt;/p&gt;&lt;/div&gt; &lt;p&gt;The first entry enforces the rule that a WCF service&amp;nbsp;endpoint with NetNamedPipe binding can only be accessed by a client process running on the same machine as the service. This is because any logon token created when a user is authenticated over a network protocol has the NETWORK USERS SID S-1-5-2 added to it by the system. &lt;/p&gt; &lt;p&gt;The second ACE allows any authenticated user which is not a network logon to have the specified access to the named pipe. The access mask 0x0012019f corresponds to the following access rights:&lt;/p&gt; &lt;div style="border-right:black 1px solid;padding-right:10px;border-top:black 1px solid;padding-left:10px;padding-bottom:10px;margin:0px auto;border-left:black 1px solid;width:95%;padding-top:10px;border-bottom:black 1px solid;text-align:left;"&gt; &lt;p&gt;0x00100000 - SYNCHRONIZE&lt;/p&gt; &lt;p&gt;0x00020000 - READ_CONTROL&lt;/p&gt; &lt;p&gt;0x00000100 - FILE_WRITE_ATTRIBUTES&lt;/p&gt; &lt;p&gt;0x00000080 - FILE_READ_ATTRIBUTES&lt;/p&gt; &lt;p&gt;0x00000010 - FILE_WRITE_EA&lt;/p&gt; &lt;p&gt;0x00000008 - FILE_READ_EA&lt;/p&gt; &lt;p&gt;0x00000004 - FILE_CREATE_PIPE_INSTANCE&lt;/p&gt; &lt;p&gt;0x00000002 - FILE_WRITE_DATA&lt;/p&gt; &lt;p&gt;0x00000001 - FILE_READ_DATA&lt;/p&gt;&lt;/div&gt; &lt;p&gt;More on this in a moment.&lt;/p&gt; &lt;p&gt;The third ACE looks a bit&amp;nbsp;odd to me. My understanding is that CREATOR OWNER is a placeholder SID which is really only relevant when a new security descriptor is being created for a new object using an existing descriptor as the pattern: if the template descriptor contains ACEs for the CREATOR OWNER SID, the corresponding ACEs in the security descriptor created for the new object have the SID for the principal which created the object. No logon token actually contains the CREATOR OWNER SID, as far as I know. Now, when an access check is being done against an ACL-protected object, only the ACEs which match a SID in the logon token are relevant to granting or denying permission. If I&amp;#39;m right that no logon token is ever going to contain the CREATOR OWNER SID,&amp;nbsp;then this third ACE on the pipe&amp;#39;s DACL will never have any function in an access check performed when a handle to the pipe is acquired. I suspect that the intention of the WCF developers was that this ACE would provide the access permissions for the service process whose channel listener created the pipe: but it doesn&amp;#39;t do this, as I will demonstrate in&amp;nbsp;a&amp;nbsp;subsequent post.&lt;/p&gt; &lt;p&gt;For the remainder of this post, let&amp;#39;s focus on that second ACE, which grants permissions to the EVERYONE group. Did you raise an eyebrow at that FILE_CREATE_PIPE_INSTANCE permission? Do we really want EVERYONE to have permission to create an instance of the service&amp;#39;s named pipe? No, we certainly do not! This is a bug in WCF which opens a serious security vulnerability.&lt;/p&gt; &lt;p&gt;The problem is that any code at all, which is able to execute on the machine where the service lives, can call the Win32 API CreateNamedPipe with appropriate arguments and get a valid server-side handle to an instance of the WCF service&amp;#39;s named pipe. It can then call ConnectNamePipe, whereupon it will&amp;nbsp;be in direct competition with the actual service for incoming client connections to the service. Sooner or later some unsuspecting client trying to send a request to the service will be allocated to&amp;nbsp;the instance of the pipe &amp;quot;owned&amp;quot; by the rogue process rather than one owned by the service. &lt;/p&gt; &lt;p&gt;At best, the client&amp;#39;s request to the service will just fail. But the rogue process might also read the data in the client&amp;#39;s request; use the client&amp;#39;s credentials by calling ImpersonateNamedPipeClient; or possibly return spoof response data to the client.&lt;/p&gt; &lt;p&gt;We really need to do something about this, but what? Can we&amp;nbsp;control the DACL&amp;nbsp;which gets put on&amp;nbsp;the pipe, when the service&amp;nbsp;runtime is created? Let&amp;#39;s deconstruct exactly where this happens...&lt;/p&gt; &lt;p&gt;The &amp;nbsp;DACL applied to a named pipe is determined by the &lt;em&gt;lpSecurityAttributes &lt;/em&gt;argument passed to Windows when CreateNamedPipe is first called:&lt;/p&gt;&lt;pre class="libCScode" id="ctl00_rs1_mainContentContainer_ctl01"&gt;HANDLE WINAPI CreateNamedPipe(
  __in      LPCTSTR &lt;i&gt;lpName&lt;/i&gt;,
  __in      DWORD &lt;i&gt;dwOpenMode&lt;/i&gt;,
  __in      DWORD &lt;i&gt;dwPipeMode&lt;/i&gt;,
  __in      DWORD &lt;i&gt;nMaxInstances&lt;/i&gt;,
  __in      DWORD &lt;i&gt;nOutBufferSize&lt;/i&gt;,
  __in      DWORD &lt;i&gt;nInBufferSize&lt;/i&gt;,
  __in      DWORD &lt;i&gt;nDefaultTimeOut&lt;/i&gt;,
  __in_opt  LPSECURITY_ATTRIBUTES &lt;i&gt;lpSecurityAttributes&lt;/i&gt;
);
&lt;/pre&gt;
&lt;p&gt;In WCF, this function is declared in System.ServiceModel.Channels.UnsafeNativeMethods, and is called by the private method CreatePipe() of System.ServiceModel.Channels.PipeConnectionListener, which is the implementation of IConnectionListener used by the service channel stack of the netNamedPipe binding. CreatePipe() is invoked when IConnectionListener.BeginAccept() is called by the service runtime. Our old friend Reflector shows us that the &lt;em&gt;lpSecurityAttributes&lt;/em&gt; argument for CreateNamedPipe() is constructed in the PipeConnectionListener.CreatePipe method, using a hard-coded constant -1073741824, and a private member field, allowedSids, of type List&amp;lt;SecurityIdentifier&amp;gt;. &lt;/p&gt;
&lt;p&gt;That constant, -1073741824, is just 0xC0000000 in decimal, which is the value of GENERIC_READ|GENERIC_WRITE (defined in &amp;nbsp;WinNT.h). This specifies the access mask which is&amp;nbsp;granted to each of the allowed SIDs. Generic access masks are translated by Windows into the corresponding standard and specific access mask bits applicable to the type of object being secured: in this case, the translated mask is the 0x0012019f we saw in the pipe DACL actually created.&lt;/p&gt;
&lt;p&gt;The list of allowed SIDs for the PipeConnectionListener is supplied in its constructor.&amp;nbsp;If we look at the NamedPipeTransportBindingElement&amp;nbsp;which defines how the transport channel is built for the netNamedPipe binding, we see that it too has a private&amp;nbsp;List&amp;lt;SecurityIdentifier&amp;gt; field, called allowedUsers, and a corresponding internal property, AllowedUsers. So it looks as though the original intention&amp;nbsp;of the WCF design was that the binding should define a set of SIDs which were to be allowed to access the pipe, and each one would get GENERIC_READ|GENERIC_WRITE access to the pipe. If this worked, it would not solve the problem that the DACL gives away FILE_CREATE_PIPE_INSTANCE rights to the pipe, but at least it would restrict access (including for that particular right) to a group of SIDs which the service configuration could control. This would&amp;nbsp;be a big improvement on giving the right away to EVERYONE&amp;nbsp;, even if it does not completely&amp;nbsp;solve the problem.&lt;/p&gt;
&lt;p&gt;Unfortunately, the plumbing does not appear to be all there in the WCF bits to make this work: the allowedUsers in the binding element is not hooked up to the allowedSids of the PipeConnectionListener when the service runtime is built. In my next post, we&amp;#39;ll look at ways to get round this.&lt;/p&gt;&lt;img src="http://blogs.charteris.com/aggbug.aspx?PostID=574" width="1" height="1"&gt;</content><author><name>chrisdi</name><uri>http://blogs.charteris.com/members/chrisdi.aspx</uri></author><category term="WCF" scheme="http://blogs.charteris.com/blogs/chrisdi/archive/tags/WCF/default.aspx" /><category term="SOA" scheme="http://blogs.charteris.com/blogs/chrisdi/archive/tags/SOA/default.aspx" /><category term="Security" scheme="http://blogs.charteris.com/blogs/chrisdi/archive/tags/Security/default.aspx" /></entry><entry><title>Exploring the WCF Named Pipe Binding - Part 1</title><link rel="alternate" type="text/html" href="http://blogs.charteris.com/blogs/chrisdi/archive/2008/05/19/exploring-the-wcf-named-pipe-binding-part-1.aspx" /><id>http://blogs.charteris.com/blogs/chrisdi/archive/2008/05/19/exploring-the-wcf-named-pipe-binding-part-1.aspx</id><published>2008-05-19T14:18:16Z</published><updated>2008-05-19T14:18:16Z</updated><content type="html">&lt;p&gt;This is the first in a series of posts in which I will aim to&amp;nbsp;explain some details of the named pipe binding provided by Windows Communication Foundation&amp;nbsp;(WCF), discovered during the course of some exploring I have been doing. My motivations for looking into this were:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;The standard binding (NetNamedPipeBinding) exposes&amp;nbsp;very few properties&amp;nbsp;relating to configuration&amp;nbsp;of the underlying transport mechanism. Having some awareness of the&amp;nbsp;Windows named pipe APIs from previous work, I was interested to understand how the WCF binding mapped to the underlying transport&amp;nbsp;protocol; which named pipe configuration options were &amp;quot;baked into&amp;quot; the WCF implementation and which might be controlled/tweaked with a bit of work in the channel stack.  &lt;li&gt;I wanted to understand in more detail the security characteristics of the binding.  &lt;li&gt;I was just nosey :-)&amp;nbsp;&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;In this post I will start by looking at the how the named pipe used by a service endpoint with the NetNamedPipe binding is created, and how clients locate it in order to connect. &lt;/p&gt; &lt;p&gt;I had expected that if I looked&amp;nbsp;into the service process using a tool like&amp;nbsp;&lt;a href="http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx" target="_blank"&gt;Process Explorer&lt;/a&gt;, I would see&amp;nbsp;it holding a handle to a named pipe with a name closely related to the URI of the endpoint. What I see instead is a handle to&amp;nbsp;a pipe named something like... &lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font color="#0000a0"&gt;\\.\pipe\197ad019-6e5f-48cb-8f88-02ae11dfd8c0 &lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;... clearly the pipe name has been created using a GUID. I also note that the name of the pipe changes each time I stop and restart my service host, so the GUID is being regenerated each time the endpoint runtime is built by WCF.&lt;/p&gt; &lt;p&gt;How then does a client of the service&amp;nbsp;know how to communicate with the endpoint? Somehow it must be able to resolve the well-known URI for the endpoint into whatever is the current name of the pipe it must use to send messages to the service. It turns out that this is accomplished using what amounts to a mini metadata publishing mechanism which is exclusive to the NetNamedPipe binding. This mechanism is based on a named Windows file mapping object backed by the system paging file. It is the name of this object which is invariant, and directly derived from the endpoint URI... though in a far from obvious way.&lt;/p&gt; &lt;p&gt;So in order to locate the correct pipe, a client of a WCF NetNamedPipe service endpoint has to:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;know that the special metadata mechanism exists  &lt;li&gt;know how to derive from the endpoint URI the name of the file mapping object through which the metadata is published  &lt;li&gt;located the file mapping object and use it to open a view&amp;nbsp;on the shared memory  &lt;li&gt;know how to interpret the metadata stored in the shared memory, and translate it into the name of the pipe currently being used by the endpoint&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Some more details for those who are interested:&lt;/p&gt; &lt;div style="border-right:black 1px solid;padding-right:10px;border-top:black 1px solid;padding-left:10px;padding-bottom:10px;margin:0px auto;border-left:black 1px solid;width:95%;padding-top:10px;border-bottom:black 1px solid;text-align:left;"&gt; &lt;p align="left"&gt;&lt;strong&gt;&lt;u&gt;Deriving the file mapping object name from the URI&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p align="left"&gt;The shared memory file mapping object created by the service endpoint listener (System.ServiceModel.Channels.PipeConnectionListener) has a name which looks something like this:&lt;/p&gt; &lt;blockquote&gt; &lt;p align="left"&gt;&lt;font color="#0000a0"&gt;net.pipe:EbmV0LnBpnGU6Ly9rL1dDRkRFTU9OUF1g6e9cUFNFUlZJQ0Uv&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p align="left"&gt;This is derived&amp;nbsp;from the&amp;nbsp;following components:&lt;/p&gt; &lt;blockquote&gt; &lt;p align="left"&gt;[&amp;quot;net.pipe&amp;quot;] [:E|:H] [base-64 encoded&amp;nbsp;byte[] X]&lt;/p&gt;&lt;/blockquote&gt; &lt;blockquote&gt; &lt;p align="left"&gt;Where the X is constructed as:&lt;/p&gt; &lt;p align="left"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; - when the second component is :E&amp;nbsp;&amp;nbsp; :&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;UTF8 encoding of&amp;nbsp;[&amp;quot;net.pipe://&amp;quot;] [URI hostname-or-wildcard*] [URI path or parent path]&lt;/p&gt; &lt;p align="left"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; - when the second component is :H&amp;nbsp;&amp;nbsp; :&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;the SHA-1&amp;nbsp;hash of the above (used when the UTF8 encoding of the above exceeds 127 bytes)&lt;/p&gt; &lt;p align="left"&gt;*The URI hostname-or-wildcard depends on the HostNameComparisonMode setting for the endpoint&amp;#39;s transport binding -&amp;nbsp;this property is set to HostNameComparisonMode.StrongWildcard&amp;nbsp;in the standard NetNamedPipeBinding, and is not exposed as a property of the binding itself. This means that this component of the name will be &amp;quot;+&amp;quot; (the strong wildcard symbol) unless a custom binding has been used to tweak the HostNameComparisonMode property of the transport binding element.&lt;/p&gt;&lt;/blockquote&gt; &lt;p align="left"&gt;&lt;strong&gt;&lt;u&gt;Data stored by the service in the shared memory object&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p align="left"&gt;The service stores 20 bytes of data in&amp;nbsp;the shared memory, representing&amp;nbsp;an instance of&amp;nbsp;the&amp;nbsp;structure System.ServiceModel.Channels.PipeSharedMemory+SharedMemoryContents, which looks like this...&lt;/p&gt; &lt;p align="left"&gt;&lt;font face="Courier New" color="#0000a0" size="2"&gt;[StructLayout(LayoutKind.Sequential)]&lt;br /&gt;struct &lt;b&gt;SharedMemoryContents&lt;/b&gt;&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public bool &lt;b&gt;isInitialized&lt;/b&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public Guid &lt;b&gt;pipeGuid&lt;/b&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New" color="#008000"&gt;&lt;font face="Trebuchet MS" color="#000000"&gt;The client uses the GUID stored in this&amp;nbsp;object to construct the pipe name through which to connect to the service endpoint.&lt;/font&gt;&lt;/p&gt;&lt;/div&gt;&lt;/font&gt; &lt;p&gt;Of course, the WCF client stack knows how to jump through these hoops, as it uses the same set of System.ServiceModel types as the service used to set up the mechanism.&amp;nbsp;So you don&amp;#39;t really need to know anything about all this if your service client is also a WCF application using the standard binding... which it will be if you are doing things as the WCF designers intended: the named pipe binding was designed&amp;nbsp;solely for&amp;nbsp;WCF-to-WCF&amp;nbsp;scenarios.&amp;nbsp;&lt;/p&gt; &lt;p&gt;That&amp;#39;s not to say that, in principle, there is any fundamental reason why a&amp;nbsp;named pipe binding&amp;nbsp;to a WCF service should not be able to support any arbitrary client implementation which knows how to write messages to and read messages from a named pipe.&amp;nbsp;Perhaps there are&amp;nbsp;integration scenarios involving legacy unmanaged code or mixed technologies on a single box, where a more open named pipe binding might be useful, not least because the underlying transport mechanism is very fast. But the standard NetNamedPipe binding won&amp;#39;t help with this. In practice, it is going to be much easier to&amp;nbsp;use&amp;nbsp;one of the&amp;nbsp;bindings based on&amp;nbsp;standard interoperable protocols, or by providing a COM wrapper around a WCF client implementation.&lt;/p&gt;&lt;img src="http://blogs.charteris.com/aggbug.aspx?PostID=556" width="1" height="1"&gt;</content><author><name>chrisdi</name><uri>http://blogs.charteris.com/members/chrisdi.aspx</uri></author><category term="WCF" scheme="http://blogs.charteris.com/blogs/chrisdi/archive/tags/WCF/default.aspx" /><category term="SOA" scheme="http://blogs.charteris.com/blogs/chrisdi/archive/tags/SOA/default.aspx" /></entry><entry><title>.NET Framework 2.0 KB928365 Patch problems</title><link rel="alternate" type="text/html" href="http://blogs.charteris.com/blogs/chrisdi/archive/2007/07/18/net-framework-2-0-kb928365-patch-problems.aspx" /><id>http://blogs.charteris.com/blogs/chrisdi/archive/2007/07/18/net-framework-2-0-kb928365-patch-problems.aspx</id><published>2007-07-18T11:59:00Z</published><updated>2007-07-18T11:59:00Z</updated><content type="html">&lt;p&gt;The build process for the project I am currently working on just got hosed by&amp;nbsp;Microsoft Security Update for Microsoft .NET Framework 2.0 (KB928365).&amp;nbsp;A hundred-odd projects which had been building correctly&amp;nbsp;for weeks or months suddenly&amp;nbsp;started to&amp;nbsp;error during solution build,&amp;nbsp;with post-build event failures complaining of file paths not found.&lt;/p&gt;
&lt;p&gt;The failing post-build events all contained constructs like:&lt;/p&gt;
&lt;p&gt;msbuild /v:m &amp;quot;$(ProjectDir)\..\Common\postbuild.proj&amp;quot; ...&lt;/p&gt;
&lt;p&gt;the error was happening because these events were now being executed as though it was&lt;/p&gt;
&lt;p&gt;msbuild /v:m &amp;quot;&amp;lt;project folder&amp;gt;\Common\postbuild.proj&amp;quot; ...&amp;nbsp; i.e. looking for the Common folder as a child of the project folder rather than its sibling.&lt;/p&gt;
&lt;p&gt;The eagle-eyed may have spotted that the expression in our project file generates a&amp;nbsp;superfluous backslash after the project folder, because the $(ProjectDir) macro is expanded by VS to include a trailing backslash. &lt;/p&gt;
&lt;p&gt;It turns out that this security patch changes&amp;nbsp;behaviour at the operating system level concerning the interpretation of file system paths containing duplicated backslash characters. Whereas the OS was previously forgiving of duplicates,&amp;nbsp;treating them just as single&amp;nbsp;backslash characters, the new behaviour&amp;nbsp;somewhat bizarrely treats&amp;nbsp;&amp;#39;\\..\&amp;#39; as though it were just &amp;#39;\&amp;#39;&amp;nbsp;.&lt;/p&gt;I&amp;#39;m wondering whether this change in behaviour is intentional,&amp;nbsp;and somehow related to a security issue, or whether it is an unintentional side effect of something MS have patched. I&amp;#39;m also wondering how many latent defects there are out there in deployed applications, which are&amp;nbsp;going to be exposed by this.&amp;nbsp;&lt;font color="#0000ff" size="2"&gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt; 
&lt;p&gt;&lt;/font&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://blogs.charteris.com/aggbug.aspx?PostID=388" width="1" height="1"&gt;</content><author><name>chrisdi</name><uri>http://blogs.charteris.com/members/chrisdi.aspx</uri></author></entry><entry><title>BizTalk starts to morph...?</title><link rel="alternate" type="text/html" href="http://blogs.charteris.com/blogs/chrisdi/archive/2007/05/01/BizTalk-starts-to-morph_2E002E002E003F00_.aspx" /><id>http://blogs.charteris.com/blogs/chrisdi/archive/2007/05/01/BizTalk-starts-to-morph_2E002E002E003F00_.aspx</id><published>2007-05-01T16:25:31Z</published><updated>2007-05-01T16:25:31Z</updated><content type="html">&lt;p&gt;Something big happened last week, the birth of a new concept: the Internet Service Bus, or as Microsoft Connected Systems division has christened it,&amp;nbsp; &lt;font color="#0000ff"&gt;&lt;a title="http://labs.biztalk.net/" href="http://labs.biztalk.net/"&gt;BizTalk Services&lt;/a&gt;&lt;/font&gt;. &amp;nbsp;Read, for example,&amp;nbsp;&lt;a href="http://www.dennispi.com/"&gt;Dennis Pilarinos&lt;/a&gt;&amp;nbsp;on what this is, and&amp;nbsp;&lt;a href="http://friends.newtelligence.net/clemensv/CommentView,guid,842e5373-60c1-4390-b820-00dba8b0cb4c.aspx"&gt;Clemens Vasters&lt;/a&gt;&amp;nbsp;on why it's important.&lt;/p&gt; &lt;p&gt;Besides being&amp;nbsp;an exteremely interesting&amp;nbsp;initiative because of what it is, I find the choice of name quite intriguing also...&amp;nbsp;is this the first public evidence of a Redmond strategy to morph BizTalk from a product to&amp;nbsp;a brand; from a messaging&amp;nbsp;application platform&amp;nbsp;to a&amp;nbsp;marketing smorgasbord of services and tools for connecting distributed systems? &lt;/p&gt; &lt;p&gt;I think it's quite likely: the advent of WCF and WF has always appeared to me as the writing on the wall for BizTalk as a single monolithic product, which the absorption of the BizTalk product group into the CSD seemed to confirm.&lt;/p&gt;&lt;img src="http://blogs.charteris.com/aggbug.aspx?PostID=284" width="1" height="1"&gt;</content><author><name>chrisdi</name><uri>http://blogs.charteris.com/members/chrisdi.aspx</uri></author><category term="WCF" scheme="http://blogs.charteris.com/blogs/chrisdi/archive/tags/WCF/default.aspx" /><category term="BizTalk" scheme="http://blogs.charteris.com/blogs/chrisdi/archive/tags/BizTalk/default.aspx" /><category term="WF" scheme="http://blogs.charteris.com/blogs/chrisdi/archive/tags/WF/default.aspx" /><category term="SOA" scheme="http://blogs.charteris.com/blogs/chrisdi/archive/tags/SOA/default.aspx" /></entry><entry><title>Throttling BizTalk service instances</title><link rel="alternate" type="text/html" href="http://blogs.charteris.com/blogs/chrisdi/archive/2007/03/06/Throttling-BizTalk-service-instances.aspx" /><id>http://blogs.charteris.com/blogs/chrisdi/archive/2007/03/06/Throttling-BizTalk-service-instances.aspx</id><published>2007-03-06T13:56:41Z</published><updated>2007-03-06T13:56:41Z</updated><content type="html">&lt;p&gt;Most of the time, performance tuning of our software is about speeding things up... why would you ever want to slow things down? Well, as it happens, there are scenarios when working with BizTalk Server where slowing things down a bit is a desirable goal. &lt;/p&gt; &lt;p&gt;A common one in BizTalk Server 2004&amp;nbsp;arises when using the SOAP send adapter which comes in the box to make calls to SOAP web services from within orchestrations. The SOAP send adapter uses the standard CLR thread pool to dispatch SOAP requests across the network, and process the responses received from the web service. Unfortunately, if you drive it too hard, at peak throughput you will start to see the send adapter logging exceptions like this&amp;nbsp;and suspending the&amp;nbsp;request messages for retry:&lt;/p&gt; &lt;p class="MsoNormal" style="margin:0cm 0cm 0pt 36pt;"&gt;&lt;span&gt;&lt;font size="1"&gt;&lt;strong&gt;Event ID 5740 - The adapter "SOAP" raised an error message. Details "There were not enough free threads in the ThreadPool object to complete the operation.&lt;o:p&gt;&lt;/o:p&gt;&lt;/strong&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt; &lt;p&gt;This is actually a symptom of a problem in the ASP.NET HTTP stack rather than in the BizTalk product itself. The issue is explained in &lt;a href="http://support.microsoft.com/default.aspx?scid=kb;en-us;821268" target="_blank"&gt;this Microsoft Knowledge Base article&lt;/a&gt;: briefly, each&amp;nbsp;SOAP request uses a worker thread to make the request, an IO completion thread to service the response, and&amp;nbsp;additional threads to perform authentication handshakes; if the available thread pool&amp;nbsp;threads are tied up on requests and there are no free threads which can be used to service responses, these errors occur. Changes were made in BizTalk Server 2004 SP1 to alleviate this problem, and the throughput limit before the problem manifests can be increased by careful tuning of the CLR thread pool parameters as described in the KB article. The problem doesn't go away completely, however. In a typical BizTalk 2004 installation with optimal tuning of the CLR parameters, spikes in throughput of more than about 150 SOAP requests per second will encounter this issue. (I'm told that the situation is much better in BizTalk Server 2006 - the ASP.NET 2.0 stack was rewritten to considerably reduce the possibility of thread pool starvation - but I do not have first-hand experience or confirmation of this).&lt;/p&gt; &lt;p&gt;Unfortunately, even if your normal peak throughput is considerably less than this limit, spikes can still occur due to temporary outages of one sort or another. BizTalk's automatic retry functionality then serves to exacerbate the problem, because the retry interval is fixed&amp;nbsp;so messages which previously failed close together in time are resubmitted in a spike. Also, when the problem starts to occur, thread pool threads affected become tied up for a fairly lengthy timeout period (100 seconds, I think) before being freed up, so the problem tends to escalate. If you need high throughput rates it is highly desirable that you avoid the problem ever occurring.&lt;/p&gt; &lt;p&gt;To this end, what we would like to be able to do is smooth out any spikes in the rate at which our orchestrations feed web service requests to the SOAP send adapter. Unfortunately, the knobs provided by BizTalk 2004 for controlling the work rate of orchestration hosts are much too blunt an instrument for doing this effectively - host throttling parameters are global to the BizTalk Group in BizTalk 2004. A different approach which I have used with some success is a fairly direct regulation of the rate at which the orchestrations execute the Send shape to the Web Port. I use a C# helper type, which I have called ExecutionBrake, which is invoked by the orchestration just before it initiates the SOAP request, and which acts as a governor controlling the peak rate at which concurrent instances can execute within that host instance. &lt;/p&gt; &lt;p&gt;The idea is to use thread synchronisation primitives within this helper type to identify when the rate of executing requests is approaching the desired limit, and apply as light a touch as possible to delay execution of just enough threads to keep the rate from peaking above the limit. Unless there is a sustained spike, short waits using System.Threading.Thread.Sleep() are sufficient. If a sustained load in excess of the limit is experienced, a fallback method is used, whereby the helper type indicates to the orchestration that it should enter a longer delay loop using a Delay shape.&lt;/p&gt; &lt;p&gt;The following sample code should illustrate the idea:&lt;/p&gt;&lt;font color="#0000ff" size="2"&gt; &lt;p&gt;&lt;font face="Courier New" size="1"&gt;using&lt;/font&gt;&lt;/font&gt;&lt;b&gt;&lt;font face="Courier New" size="1"&gt; System;&lt;br&gt;&lt;/font&gt;&lt;/b&gt;&lt;font color="#0000ff"&gt;&lt;font face="Courier New" size="1"&gt;using&lt;/font&gt;&lt;/font&gt;&lt;b&gt;&lt;font face="Courier New" size="1"&gt; System.Collections;&lt;/font&gt;&lt;br&gt;&lt;/b&gt;&lt;font color="#0000ff"&gt;&lt;font face="Courier New" size="1"&gt;using&lt;/font&gt;&lt;/font&gt;&lt;b&gt;&lt;font face="Courier New" size="1"&gt; System.Threading;&lt;/font&gt;&lt;/p&gt;&lt;/b&gt;&lt;font color="#0000ff"&gt; &lt;p&gt;&lt;font face="Courier New" size="1"&gt;namespace&lt;/font&gt;&lt;/font&gt;&lt;b&gt;&lt;font face="Courier New" size="1"&gt; Charteris.ChrisDicksonBlog.Samples&lt;/font&gt;&lt;br&gt;&lt;font face="Courier New" size="1"&gt;{&lt;/font&gt;&lt;/b&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="1"&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;&amp;nbsp;public&lt;/font&gt;&lt;b&gt; &lt;/b&gt;&lt;font color="#0000ff"&gt;class&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;b&gt;&lt;font face="Courier New" size="1"&gt; ExecutionBrake&lt;/font&gt;&lt;br&gt;&lt;font face="Courier New" size="1"&gt;&amp;nbsp;{&lt;/font&gt;&lt;/p&gt;&lt;/b&gt; &lt;p&gt;&lt;font size="1"&gt;&lt;font face="Courier New"&gt;&lt;font color="#808080"&gt;&amp;nbsp;///&lt;/font&gt;&lt;font color="#008000"&gt; &lt;/font&gt;&lt;font color="#808080"&gt;&amp;lt;summary&amp;gt;&lt;br&gt;&amp;nbsp;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;b&gt;&lt;/b&gt;&lt;font size="1"&gt;&lt;font face="Courier New"&gt;&lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#008000"&gt; Maintains a register of the named instances which are active in the &lt;br&gt;&amp;nbsp;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;b&gt;&lt;/b&gt;&lt;font size="1"&gt;&lt;font face="Courier New"&gt;&lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#008000"&gt; current AppDomain. For any unique name, the braking is implemented by &lt;br&gt;&amp;nbsp;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;b&gt;&lt;/b&gt;&lt;font size="1"&gt;&lt;font face="Courier New"&gt;&lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#008000"&gt; an internal Singleton object.&lt;br&gt;&amp;nbsp;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;b&gt;&lt;/b&gt;&lt;font size="1"&gt;&lt;font face="Courier New"&gt;&lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#008000"&gt; &lt;/font&gt;&lt;font color="#808080"&gt;&amp;lt;/summary&amp;gt;&lt;br&gt;&amp;nbsp;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;b&gt;&lt;/b&gt;&lt;font size="1"&gt;&lt;font face="Courier New"&gt;&lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#008000"&gt; &lt;/font&gt;&lt;font color="#808080"&gt;&amp;lt;param name="uniqueName"&amp;gt;&lt;/font&gt;&lt;font color="#008000"&gt;Unique brake name to register&lt;/font&gt;&lt;font color="#808080"&gt;&amp;lt;/param&amp;gt;&lt;br&gt;&amp;nbsp;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;b&gt;&lt;/b&gt;&lt;font size="1"&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;private&lt;/font&gt;&lt;b&gt; &lt;/b&gt;&lt;font color="#0000ff"&gt;static&lt;/font&gt;&lt;b&gt; &lt;/b&gt;&lt;font color="#0000ff"&gt;void&lt;/font&gt;&lt;b&gt; RegisterBrake(&lt;/b&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;b&gt;&lt;font face="Courier New" size="1"&gt; uniqueName)&lt;/font&gt;&lt;br&gt;&amp;nbsp;&lt;font face="Courier New" size="1"&gt;{&lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &lt;/b&gt;&lt;font face="Courier New" color="#0000ff" size="1"&gt;if&lt;/font&gt;&lt;b&gt;&lt;font face="Courier New" size="1"&gt; (!_brakingImplementations.ContainsKey(uniqueName))&lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &lt;font face="Courier New" size="1"&gt;{&lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/b&gt;&lt;font face="Courier New" color="#0000ff" size="1"&gt;lock&lt;/font&gt;&lt;b&gt;&lt;font face="Courier New" size="1"&gt; (_sync)&lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font face="Courier New" size="1"&gt;{&lt;/font&gt;&lt;/b&gt;&lt;br&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/strong&gt;&lt;font face="Courier New" color="#0000ff" size="1"&gt;if&lt;/font&gt;&lt;b&gt;&lt;font face="Courier New" size="1"&gt; (!_brakingImplementations.ContainsKey(uniqueName))&lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font face="Courier New" size="1"&gt;{&lt;/font&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; &lt;font face="Courier New" size="1"&gt;ExecutionBrakeImpl impl = &lt;/font&gt;&lt;/b&gt;&lt;font face="Courier New" color="#0000ff" size="1"&gt;new&lt;/font&gt;&lt;b&gt;&lt;font face="Courier New" size="1"&gt; ExecutionBrakeImpl();&lt;/font&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; &lt;font face="Courier New" size="1"&gt;Thread.MemoryBarrier();&lt;/font&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; &lt;font face="Courier New" size="1"&gt;_brakingImplementations.Add(uniqueName, impl);&lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font face="Courier New" size="1"&gt;}&lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font face="Courier New" size="1"&gt;}&lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &lt;font face="Courier New" size="1"&gt;}&lt;/font&gt;&lt;br&gt;&amp;nbsp;&lt;font face="Courier New" size="1"&gt;}&lt;/font&gt;&lt;/p&gt;&lt;/b&gt; &lt;p&gt;&lt;font size="1"&gt;&lt;font face="Courier New"&gt;&lt;font color="#808080"&gt;&amp;nbsp;///&lt;/font&gt;&lt;font color="#008000"&gt; &lt;/font&gt;&lt;font color="#808080"&gt;&amp;lt;summary&amp;gt;&lt;br&gt;&amp;nbsp;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;b&gt;&lt;/b&gt;&lt;font size="1"&gt;&lt;font face="Courier New"&gt;&lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#008000"&gt; Collection of singleton implementation objects, keyed on unique name&lt;br&gt;&amp;nbsp;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;b&gt;&lt;/b&gt;&lt;font size="1"&gt;&lt;font face="Courier New"&gt;&lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#008000"&gt; &lt;/font&gt;&lt;font color="#808080"&gt;&amp;lt;/summary&amp;gt;&lt;br&gt;&amp;nbsp;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;b&gt;&lt;/b&gt;&lt;font size="1"&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;private&lt;/font&gt;&lt;b&gt; &lt;/b&gt;&lt;font color="#0000ff"&gt;static&lt;/font&gt;&lt;b&gt; Hashtable _brakingImplementations = &lt;/b&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;b&gt;&lt;font face="Courier New" size="1"&gt; Hashtable();&lt;br&gt;&amp;nbsp;&lt;/font&gt;&amp;nbsp;&lt;/b&gt;&lt;font size="1"&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;private&lt;/font&gt;&lt;b&gt; &lt;/b&gt;&lt;font color="#0000ff"&gt;static&lt;/font&gt;&lt;b&gt; &lt;/b&gt;&lt;font color="#0000ff"&gt;object&lt;/font&gt;&lt;b&gt; _sync = &lt;/b&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;b&gt; &lt;/b&gt;&lt;font color="#0000ff"&gt;object&lt;/font&gt;&lt;b&gt;();&lt;/b&gt;&lt;/font&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="1"&gt;&lt;font face="Courier New"&gt;&lt;b&gt;&lt;br&gt;&lt;/b&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;&amp;nbsp;public&lt;/font&gt;&lt;b&gt; ExecutionBrake(&lt;/b&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;b&gt;&lt;font face="Courier New" size="1"&gt; uniqueName)&lt;/font&gt;&lt;br&gt;&amp;nbsp;&lt;font face="Courier New" size="1"&gt;{&lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font face="Courier New" size="1"&gt;_uniqueName = uniqueName;&lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font face="Courier New" size="1"&gt;RegisterBrake(uniqueName);&lt;/font&gt;&lt;br&gt;&amp;nbsp;&lt;font face="Courier New" size="1"&gt;}&lt;/font&gt;&lt;/p&gt;&lt;/b&gt;&lt;b&gt; &lt;p&gt;&lt;/b&gt;&lt;font size="1"&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;&lt;font color="#808080"&gt;&amp;nbsp;///&lt;/font&gt;&lt;font color="#008000"&gt; &lt;/font&gt;&lt;font color="#808080"&gt;&amp;lt;summary&amp;gt;&lt;br&gt;&amp;nbsp;&lt;/font&gt;&lt;b&gt;&lt;/b&gt;&lt;font size="1"&gt;&lt;font face="Courier New"&gt;&lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#008000"&gt;&amp;nbsp;Key method&amp;nbsp;called by the orchestration. If the return&amp;nbsp;value is zero, the orchestration&lt;br&gt;&amp;nbsp;&lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#008000"&gt;&amp;nbsp;continues to make the SOAP request. If non-zero, the orchestration should loop via a&amp;nbsp;&lt;/font&gt;&lt;br&gt;&amp;nbsp;&lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#008000"&gt;&amp;nbsp;Delay shape and call this method again before proceeding. The return value&amp;nbsp;can be used&lt;/font&gt;&lt;br&gt;&amp;nbsp;&lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#008000"&gt;&amp;nbsp;to seed the Delay shape's configuration, so that retries are spread randomly.&amp;nbsp;&lt;/font&gt;&lt;br&gt;&amp;nbsp;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;b&gt;&lt;/b&gt;&lt;font size="1"&gt;&lt;font face="Courier New"&gt;&lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#008000"&gt; &lt;/font&gt;&lt;font color="#808080"&gt;&amp;lt;/summary&amp;gt;&lt;br&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&amp;nbsp;public&lt;/font&gt;&lt;b&gt; &lt;/b&gt;&lt;font color="#0000ff"&gt;int&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;b&gt;&lt;font face="Courier New" size="1"&gt; ThrottleExecution()&lt;/font&gt;&lt;br&gt;&amp;nbsp;&lt;font face="Courier New" size="1"&gt;{&lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/b&gt;&lt;font face="Courier New" color="#0000ff" size="1"&gt;return&lt;/font&gt;&lt;b&gt;&lt;font face="Courier New" size="1"&gt; ((ExecutionBrakeImpl)_brakingImplementations[_uniqueName]).ThrottleExecution();&lt;/font&gt;&lt;br&gt;&amp;nbsp;&lt;font face="Courier New" size="1"&gt;}&lt;/font&gt;&lt;/p&gt;&lt;/b&gt;&lt;b&gt; &lt;p&gt;&lt;/b&gt;&lt;font size="1"&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;&amp;nbsp;private&lt;/font&gt;&lt;b&gt; &lt;/b&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;b&gt; _uniqueName;&lt;br&gt;&lt;/b&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New" color="#0000ff" size="1"&gt;&lt;/p&gt;&lt;/font&gt;&lt;b&gt; &lt;p&gt;&lt;/b&gt;&lt;font size="1"&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;&amp;nbsp;private&lt;/font&gt;&lt;b&gt; &lt;/b&gt;&lt;font color="#0000ff"&gt;class&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;b&gt;&lt;font face="Courier New" size="1"&gt; ExecutionBrakeImpl&lt;/font&gt;&lt;br&gt;&amp;nbsp;&lt;font face="Courier New" size="1"&gt;{&lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/b&gt;&lt;font size="1"&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;b&gt; &lt;/b&gt;&lt;font color="#0000ff"&gt;int&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;b&gt;&lt;font face="Courier New" size="1"&gt; ThrottleExecution()&lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font face="Courier New" size="1"&gt;{&lt;/font&gt;&lt;br&gt;&lt;/p&gt; &lt;p&gt;&lt;/b&gt;&lt;font color="#008000"&gt;&lt;font face="Courier New" size="1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Maintain a count of threads currently executing this method. The corresponding&lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;b&gt;&lt;/b&gt;&lt;font color="#008000"&gt;&lt;font face="Courier New" size="1"&gt;// decrement is in the finally block&lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;b&gt;&lt;/b&gt;&lt;font size="1"&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;int&lt;/font&gt;&lt;b&gt; threadsInThisMethod = Interlocked.Increment(&lt;/b&gt;&lt;font color="#0000ff"&gt;ref&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;b&gt;&lt;font face="Courier New" size="1"&gt; _threadsUnderControlCount);&lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/b&gt;&lt;font color="#0000ff"&gt;&lt;font face="Courier New" size="1"&gt;try&lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;b&gt;&lt;font face="Courier New" size="1"&gt;{&lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/b&gt;&lt;font face="Courier New" color="#0000ff" size="1"&gt;if&lt;/font&gt;&lt;b&gt;&lt;font face="Courier New" size="1"&gt; (threadsInThisMethod &amp;gt;= _deferThreshold)&lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font face="Courier New" size="1"&gt;{&lt;/font&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; &lt;/b&gt;&lt;font color="#008000"&gt;&lt;font face="Courier New" size="1"&gt;// We have more than enough threads already so defer this one immediately&lt;/font&gt;&lt;br&gt;&lt;/font&gt;&lt;font face="Courier New" color="#0000ff" size="1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&lt;/font&gt;&lt;b&gt;&lt;font face="Courier New" size="1"&gt; _random.Next(_maximumDeferralDurationHint);&lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font face="Courier New" size="1"&gt;}&lt;/font&gt;&lt;/p&gt;&lt;/b&gt;&lt;b&gt; &lt;p&gt;&lt;/b&gt;&lt;font face="Courier New" color="#0000ff" size="1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int&lt;/font&gt;&lt;b&gt;&lt;font face="Courier New" size="1"&gt; numberOfSleeps = 0;&lt;/font&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; &lt;/b&gt;&lt;font face="Courier New" color="#0000ff" size="1"&gt;if&lt;/font&gt;&lt;b&gt;&lt;font face="Courier New" size="1"&gt; (_threadsReleasedThisIntervalCount &amp;gt;= _brakingThreshold)&lt;/font&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; &lt;font face="Courier New" size="1"&gt;{&lt;/font&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; &lt;/b&gt;&lt;font color="#008000"&gt;&lt;font face="Courier New" size="1"&gt;// We have already reached the limit of threads which can be released in&lt;/font&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; &lt;/font&gt;&lt;b&gt;&lt;/b&gt;&lt;font color="#008000"&gt;&lt;font face="Courier New" size="1"&gt;// the current reference interval, so this thread must wait&lt;/font&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; &lt;/font&gt;&lt;b&gt;&lt;font face="Courier New" size="1"&gt;++numberOfSleeps;&lt;/font&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;&lt;font face="Courier New" size="1"&gt;Thread.Sleep(_random.Next(_maximumThreadSleepDuration));&lt;/font&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; &lt;font face="Courier New" size="1"&gt;}&lt;/font&gt;&lt;/p&gt;&lt;/b&gt;&lt;b&gt; &lt;p&gt;&lt;/b&gt;&lt;font color="#008000"&gt;&lt;font face="Courier New" size="1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Keep checking for a release window, then sleeping, alternately until this thread has&lt;/font&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; &lt;/font&gt;&lt;b&gt;&lt;/b&gt;&lt;font color="#008000"&gt;&lt;font face="Courier New" size="1"&gt;// either been released or has used the maximum number of sleeps&lt;/font&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; &lt;/font&gt;&lt;b&gt;&lt;/b&gt;&lt;font face="Courier New" color="#0000ff" size="1"&gt;while&lt;/font&gt;&lt;b&gt;&lt;font face="Courier New" size="1"&gt; (numberOfSleeps &amp;lt; _maximumThreadSleeps)&lt;/font&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; &lt;font face="Courier New" size="1"&gt;{&lt;/font&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; &lt;/b&gt;&lt;font face="Courier New" color="#0000ff" size="1"&gt;lock&lt;/font&gt;&lt;b&gt;&lt;font face="Courier New" size="1"&gt; (_sync)&lt;/font&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; &lt;font face="Courier New" size="1"&gt;{&lt;/font&gt;&lt;br&gt;&lt;/p&gt;&lt;/b&gt;&lt;b&gt; &lt;p&gt;&lt;/b&gt;&lt;font color="#008000"&gt;&lt;font face="Courier New" size="1"&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; // If the reference period has ended, we can start a new one and&lt;/font&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;&amp;nbsp; &lt;/font&gt;&lt;b&gt;&lt;/b&gt;&lt;font color="#008000"&gt;&lt;font face="Courier New" size="1"&gt;// be the first thread released in the new period&lt;/font&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;&amp;nbsp; &lt;/font&gt;&lt;b&gt;&lt;/b&gt;&lt;font face="Courier New" color="#0000ff" size="1"&gt;if&lt;/font&gt;&lt;b&gt;&lt;font face="Courier New" size="1"&gt; (0 &amp;gt; DateTime.Compare(_endOfControlInterval, DateTime.Now))&lt;/font&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;&amp;nbsp; &lt;font face="Courier New" size="1"&gt;{&lt;/font&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font face="Courier New" size="1"&gt;_endOfControlInterval = DateTime.Now + _thresholdInterval;&lt;/font&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font face="Courier New" size="1"&gt;_threadsReleasedThisIntervalCount = 1;&lt;/font&gt;&lt;br&gt;&lt;/b&gt;&lt;font face="Courier New" color="#0000ff" size="1"&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; return&lt;/font&gt;&lt;b&gt;&lt;font face="Courier New" size="1"&gt; 0;&lt;/font&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;&amp;nbsp;&amp;nbsp;&lt;font face="Courier New" size="1"&gt;}&lt;/font&gt;&lt;/b&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; &lt;font color="#008000"&gt;&lt;font face="Courier New" size="1"&gt;// Otherwise we can go if the count for the current interval hasn't been exceeded&lt;/font&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;&amp;nbsp;&lt;/font&gt;&lt;font face="Courier New" color="#0000ff" size="1"&gt;if&lt;/font&gt;&lt;b&gt;&lt;font face="Courier New" size="1"&gt; (_threadsReleasedThisIntervalCount &amp;lt; _brakingThreshold)&lt;/font&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; &lt;font face="Courier New" size="1"&gt;{&lt;/font&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font face="Courier New" size="1"&gt;++_threadsReleasedThisIntervalCount;&lt;/font&gt;&lt;br&gt;&lt;/b&gt;&lt;font face="Courier New" color="#0000ff" size="1"&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; return&lt;/font&gt;&lt;b&gt;&lt;font face="Courier New" size="1"&gt; 0;&lt;/font&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; &lt;font face="Courier New" size="1"&gt;}&lt;/font&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; &lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;font color="#008000"&gt;&lt;font face="Courier New" size="1"&gt;// Otherwise we'll need to sleep and loop again&lt;/font&gt;&lt;br&gt;&lt;/font&gt;&lt;b&gt;&lt;font face="Courier New" size="1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&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; &lt;font face="Courier New" size="1"&gt;++numberOfSleeps;&lt;/font&gt;&lt;br&gt;&lt;font face="Courier New" size="1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Thread.Sleep(_random.Next(_maximumThreadSleepDuration));&lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font face="Courier New" size="1"&gt;}&lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font face="Courier New" size="1"&gt;}&lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/b&gt;&lt;font color="#0000ff"&gt;&lt;font face="Courier New" size="1"&gt;finally&lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;b&gt;&lt;font face="Courier New" size="1"&gt;{&lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font face="Courier New" size="1"&gt;Interlocked.Decrement(&lt;/font&gt;&lt;/b&gt;&lt;font face="Courier New" color="#0000ff" size="1"&gt;ref&lt;/font&gt;&lt;b&gt;&lt;font face="Courier New" size="1"&gt; _threadsUnderControlCount);&lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font face="Courier New" size="1"&gt;}&lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;font color="#008000"&gt;&lt;font face="Courier New" size="1"&gt;// We were not able to release the thread, so return a non-zero deferral hint&lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;b&gt;&lt;/b&gt;&lt;font face="Courier New" color="#0000ff" size="1"&gt;return&lt;/font&gt;&lt;b&gt;&lt;font face="Courier New" size="1"&gt; _random.Next(_maximumDeferralDurationHint);&lt;/font&gt;&lt;br&gt;&amp;nbsp;&lt;font face="Courier New" size="1"&gt;}&lt;/font&gt;&lt;br&gt;&amp;nbsp; &lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;font face="Courier New" color="#0000ff" size="1"&gt;private&lt;/font&gt;&lt;b&gt;&lt;font face="Courier New" size="1"&gt; DateTime _endOfControlInterval = DateTime.Now; &lt;/font&gt;&lt;br&gt;&amp;nbsp; &lt;/b&gt;&lt;font size="1"&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;private&lt;/font&gt;&lt;b&gt; &lt;/b&gt;&lt;font color="#0000ff"&gt;int&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;b&gt;&lt;font face="Courier New" size="1"&gt; _threadsUnderControlCount; &lt;/font&gt;&lt;br&gt;&amp;nbsp; &lt;/b&gt;&lt;font size="1"&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;private&lt;/font&gt;&lt;b&gt; &lt;/b&gt;&lt;font color="#0000ff"&gt;int&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;b&gt;&lt;font face="Courier New" size="1"&gt; _threadsReleasedThisIntervalCount; &lt;/font&gt;&lt;br&gt;&amp;nbsp; &lt;/b&gt;&lt;font size="1"&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;private&lt;/font&gt;&lt;b&gt; &lt;/b&gt;&lt;font color="#0000ff"&gt;object&lt;/font&gt;&lt;b&gt; _sync = &lt;/b&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;b&gt; &lt;/b&gt;&lt;font color="#0000ff"&gt;object&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;b&gt;&lt;font face="Courier New" size="1"&gt;(); &lt;/font&gt;&lt;br&gt;&amp;nbsp; &lt;/b&gt;&lt;font size="1"&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;private&lt;/font&gt;&lt;b&gt; Random _random = &lt;/b&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;b&gt; Random();&amp;nbsp;&lt;br&gt;&amp;nbsp; &lt;/b&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#008000"&gt;&lt;font face="Courier New" size="1"&gt;// Configuration parameters. &lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;b&gt;&lt;/b&gt;&lt;font color="#008000"&gt;&lt;font face="Courier New" size="1"&gt;// For the purposes of this sample these are constants, but&lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;b&gt;&lt;/b&gt;&lt;font color="#008000"&gt;&lt;font face="Courier New" size="1"&gt;// in practice they would need some configuration mechanism&lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;b&gt;&lt;/b&gt;&lt;font color="#008000"&gt;&lt;font face="Courier New" size="1"&gt;// to tune the braking for any particular named brake.&lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;b&gt;&lt;/b&gt;&lt;font size="1"&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;private&lt;/font&gt;&lt;b&gt; &lt;/b&gt;&lt;font color="#0000ff"&gt;const&lt;/font&gt;&lt;b&gt; &lt;/b&gt;&lt;font color="#0000ff"&gt;int&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;b&gt;&lt;font face="Courier New" size="1"&gt; _brakingThreshold = 100; &lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &lt;/b&gt;&lt;font size="1"&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;private&lt;/font&gt;&lt;b&gt; &lt;/b&gt;&lt;font color="#0000ff"&gt;const&lt;/font&gt;&lt;b&gt; &lt;/b&gt;&lt;font color="#0000ff"&gt;int&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;b&gt;&lt;font face="Courier New" size="1"&gt; _deferThreshold = 200; &lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &lt;/b&gt;&lt;font size="1"&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;private&lt;/font&gt;&lt;b&gt; TimeSpan _thresholdInterval = &lt;/b&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;b&gt;&lt;font face="Courier New" size="1"&gt; TimeSpan(0,0,0,1); &lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &lt;/b&gt;&lt;font size="1"&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;private&lt;/font&gt;&lt;b&gt; &lt;/b&gt;&lt;font color="#0000ff"&gt;const&lt;/font&gt;&lt;b&gt; &lt;/b&gt;&lt;font color="#0000ff"&gt;int&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;b&gt;&lt;font face="Courier New" size="1"&gt; _maximumThreadSleepDuration = 150; &lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &lt;/b&gt;&lt;font size="1"&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;private&lt;/font&gt;&lt;b&gt; &lt;/b&gt;&lt;font color="#0000ff"&gt;const&lt;/font&gt;&lt;b&gt; &lt;/b&gt;&lt;font color="#0000ff"&gt;int&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;b&gt;&lt;font face="Courier New" size="1"&gt; _maximumThreadSleeps = 3; &lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &lt;/b&gt;&lt;font size="1"&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;private&lt;/font&gt;&lt;b&gt; &lt;/b&gt;&lt;font color="#0000ff"&gt;const&lt;/font&gt;&lt;b&gt; &lt;/b&gt;&lt;font color="#0000ff"&gt;int&lt;/font&gt;&lt;b&gt; _maximumDeferralDurationHint = 500; &lt;br&gt;&lt;/b&gt;&lt;/font&gt;&lt;/font&gt;&lt;b&gt;&lt;font face="Courier New" size="1"&gt;&amp;nbsp; }&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New" size="1"&gt;&amp;nbsp;}&lt;br&gt;&lt;/font&gt;&lt;/b&gt;&lt;b&gt;&lt;font face="Courier New" size="1"&gt;}&lt;/font&gt;&lt;/p&gt;&lt;/b&gt; &lt;p&gt;Naturally, if there are multiple host instances executing the orchestration, this braking mechanism smooths the rate of execution of each one independently, and the parameters need to be configured with this is mind.&lt;/p&gt; &lt;p&gt;Don't expect such a mechanism to enable very precise regulation of execution rates, particularly with multiple host instances, but it can be used effectively to prevent abnormal spikes in message volumes causing the sort of problems described above with the SOAP adapter.&lt;/p&gt;&lt;img src="http://blogs.charteris.com/aggbug.aspx?PostID=226" width="1" height="1"&gt;</content><author><name>chrisdi</name><uri>http://blogs.charteris.com/members/chrisdi.aspx</uri></author><category term="BizTalk" scheme="http://blogs.charteris.com/blogs/chrisdi/archive/tags/BizTalk/default.aspx" /></entry><entry><title>Windows Workflow: what it is and isn't</title><link rel="alternate" type="text/html" href="http://blogs.charteris.com/blogs/chrisdi/archive/2007/01/30/Windows-Workflow_3A00_-what-it-is-and-isn_2700_t.aspx" /><id>http://blogs.charteris.com/blogs/chrisdi/archive/2007/01/30/Windows-Workflow_3A00_-what-it-is-and-isn_2700_t.aspx</id><published>2007-01-30T17:50:39Z</published><updated>2007-01-30T17:50:39Z</updated><content type="html">&lt;p&gt;I have been meaning for some time to post about my enthusiasm for Dharma Shukla and Bob Schmidt's wonderful book &lt;a href="http://www.amazon.co.uk/Essential-Workflow-Foundation-Microsoft-Development/dp/0321399838"&gt;Essential Windows Workflow Foundation&lt;/a&gt;. In the best tradition of "Essential ..." titles started by Don Box's book on COM, they explain&amp;nbsp;what&amp;nbsp;WF is for, and how it is built, in a clear&amp;nbsp;and thorough way. The emphasis is on explanation of the principles and the abstractions which make up the&amp;nbsp;framework,&amp;nbsp;at a good level of technical detail but in an easy to follow way. Quite a contrast with the MSDN documentation for WF, it has to be said.&lt;/p&gt; &lt;p&gt;The first chapter&amp;nbsp;by itself is a masterpiece: not a single line of WF code, but a methodical deconstruction of&amp;nbsp;a simple "Hello, World!"&amp;nbsp;console application which along the way elucidates brilliantly all the reasons why WF exists. &lt;/p&gt; &lt;p&gt;This is so, so much more helpful than all those courses, presentations&amp;nbsp;and magazine articles which start and end with the Visual Studio Workflow Designer, and foster&amp;nbsp;the widespread&amp;nbsp;misconception that WF is all about programming with pictures. This book places&amp;nbsp;discussion of graphical designers&amp;nbsp;where it deserves to be, in a few short sections at the end of the last chapter ("Miscellanea"), after a comprehensive demonstration, over the previous 7 chapters, of what can be achieved with WF without&amp;nbsp;once invoking&amp;nbsp;the VS designer. &lt;/p&gt; &lt;p&gt;I would urge anyone who&amp;nbsp;found the last paragraph surprising or&amp;nbsp;controversial, to get and read a copy of the book as&amp;nbsp;soon as possible. Because WF is&amp;nbsp;NOT about&amp;nbsp;drawing flowcharts and turning them into programs: it is about the efficient implementation of distributed systems for executing long-lived processes&amp;nbsp;(perhaps very many concurrent instances of each process)&amp;nbsp;which may spend much of their time&amp;nbsp;in a passive state waiting for some external stimulus to reawaken them to execute their next step. &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;img src="http://blogs.charteris.com/aggbug.aspx?PostID=191" width="1" height="1"&gt;</content><author><name>chrisdi</name><uri>http://blogs.charteris.com/members/chrisdi.aspx</uri></author><category term="WF" scheme="http://blogs.charteris.com/blogs/chrisdi/archive/tags/WF/default.aspx" /></entry><entry><title>BizTalk Orchestration Exception Handling: What's changed?</title><link rel="alternate" type="text/html" href="http://blogs.charteris.com/blogs/chrisdi/archive/2006/12/19/BizTalk-Orchestration-Exception-Handling_3A00_-What_2700_s-changed_3F00_.aspx" /><id>http://blogs.charteris.com/blogs/chrisdi/archive/2006/12/19/BizTalk-Orchestration-Exception-Handling_3A00_-What_2700_s-changed_3F00_.aspx</id><published>2006-12-19T18:03:04Z</published><updated>2006-12-19T18:03:04Z</updated><content type="html">&lt;p&gt;One thing which has changed significantly between BizTalk Server 2004 and BizTalk Server 2006 is the way that the product behaves when unhandled exceptions occur during execution of an orchestration.&lt;/p&gt; &lt;p&gt;In BizTalk Server 2004, the model is brutally straightforward: any exception which is not caught and handled in an exception handler block suspends the orchestration instance in a state (Suspended(Not Resumeable)) from which it cannot be resurrected, and&amp;nbsp;BizTalk's XLANG/s engine logs an error&amp;nbsp;event in the Application event log looking like this:&lt;/p&gt; &lt;p&gt;&lt;font face="Microsoft Sans Serif" color="#800000" size="1"&gt;Event Type: Error&lt;br&gt;Event Source: XLANG/s&lt;br&gt;Event Category: None&lt;br&gt;Event ID: 10034&lt;br&gt;Date: 21/11/2006&lt;br&gt;Time: 15:56:20&lt;br&gt;User: N/A&lt;br&gt;Computer: CHRISDI-VM1&lt;br&gt;Description:&lt;br&gt;Uncaught exception terminated service BTSDefaultExceptions.BizTalk_Orchestration1(b08ac914-74bc-6032-8029-29cd7aeb5541), instance 497a22a5-0e93-4cc4-8fd8-43499e58e3ea &lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Microsoft Sans Serif" color="#800000" size="1"&gt;Invalid data: Some text&lt;br&gt;Exception type: ApplicationException&lt;br&gt;Source: ExceptionGenerator&lt;br&gt;Target Site: Void DoNotALot(System.String)&lt;br&gt;Help Link: &lt;br&gt;Additional error information: &lt;/font&gt; &lt;p&gt;&lt;font face="Microsoft Sans Serif" color="#800000" size="1"&gt;For more information, see Help and Support Center at &lt;/font&gt;&lt;a href="http://go.microsoft.com/fwlink/events.asp"&gt;&lt;font face="Microsoft Sans Serif" color="#800000" size="1"&gt;http://go.microsoft.com/fwlink/events.asp&lt;/font&gt;&lt;/a&gt;&lt;font face="Microsoft Sans Serif" color="#800000" size="1"&gt;.&lt;/font&gt;  &lt;p&gt;This behaviour creates&amp;nbsp;some major&amp;nbsp;problems for applications:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;it is often impossible to tell from the limited information in the event log entry what caused the failure  &lt;li&gt;the orchestration state cannot be retrieved  &lt;li&gt;messages associated with the failed orchestration can only be recovered by using&amp;nbsp;HAT to dump them out to a file, or by implementing special recovery code using WMI  &lt;li&gt;The suspended service instances remain clogging up the MessageBox until they are purged by administrative action&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;As a result, it is imperative when developing orchestrations in BizTalk Server 2004:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;to adopt&amp;nbsp;a standard pattern which provides a last-resort exception handler: that is, a scope containing&amp;nbsp;catch blocks for both .NET exceptions of type System.Exception and General Exceptions, in which a more informative description of the exception context can be constructed and&amp;nbsp;used as the Message property of a&amp;nbsp;new exception which&amp;nbsp;is then&amp;nbsp;rethrown; this mitigates&amp;nbsp;the first issue above,&amp;nbsp;as the richer context information will then&amp;nbsp;appear in the XLANG/s event log entry.  &lt;li&gt;to implement recovery logic explicitly for any exception types which can be anticipated. This logic might comprise:  &lt;ul&gt; &lt;li&gt;compensation of work already committed within atomic scopes  &lt;li&gt;retry loops&amp;nbsp;using the Suspend shape&amp;nbsp;(e.g. to handle temporary resource outages such as network connectivity failures);  &lt;li&gt;business process level error handling (e.g. sending a response message containing an error status following a data validation exception).  &lt;li&gt;graceful termination of the orchestration with appropriate logging, in the event of unrecoverable exceptions&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Essentially, the aim in BizTalk 2004 must be to avoid the XLANG/s default exception handling behaviour completely.&lt;/p&gt; &lt;p&gt;BizTalk Server 2006's exception handling model is quite different: an exception which is not caught within the exception handlers of the orchestration causes the orchestration instance to be moved to the Suspended (Resumeable) state, rather than Suspended (Non-resumeable). An event log error entry is still written by XLANG/s, but it contains more context information, including the name of the orchestration shape where the exception emerged and the stack trace at the exception site (as well as some bad spelling ;-)):&lt;/p&gt; &lt;p&gt;&lt;font face="Microsoft Sans Serif" color="#800000" size="1"&gt;Event Type:&amp;nbsp;Error&lt;br&gt;Event Source:&amp;nbsp;XLANG/s&lt;br&gt;Event Category:&amp;nbsp;None&lt;br&gt;Event ID:&amp;nbsp;10034&lt;br&gt;Date:&amp;nbsp;&amp;nbsp;21/11/2006&lt;br&gt;Time:&amp;nbsp;&amp;nbsp;11:20:42&lt;br&gt;User:&amp;nbsp;&amp;nbsp;N/A&lt;br&gt;Computer:&amp;nbsp;VM-WS2K3&lt;br&gt;Description:&lt;br&gt;Uncaught exception (see the 'inner exception' below) has suspended an instance of service 'BizTalk_Server_Project1.BizTalk_Orchestration1(872ef22d-51f6-5cde-aaa0-5a7dcc036b3b)'.&lt;br&gt;The service instance will remain suspended until administratively resumed or terminated. &lt;br&gt;If resumed the instance will continue from its last persisted state and may re-throw the same unexpected exception.&lt;br&gt;InstanceId: 014e260d-336c-458e-9d47-829afbe9148a&lt;br&gt;Shape name: Expression_1&lt;br&gt;ShapeId: 17d5c466-163b-460e-8372-cf385835b397&lt;br&gt;Exception thrown from: segment 1, progress 6&lt;br&gt;Inner exception: We don't like the name 'name_0'!&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;Exception type: ApplicationException&lt;br&gt;Source: ClassLibrary1&lt;br&gt;Target Site: Void .ctor(System.String)&lt;br&gt;The following is a stack trace that identifies the location where the exception occured&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Microsoft Sans Serif" color="#800000" size="1"&gt;&amp;nbsp;&amp;nbsp; at ClassLibrary1.Class1..ctor(String name)&lt;br&gt;&amp;nbsp;&amp;nbsp; at BizTalk_Server_Project1.BizTalk_Orchestration1.segment1(StopConditions stopOn)&lt;br&gt;&amp;nbsp;&amp;nbsp; at Microsoft.XLANGs.Core.SegmentScheduler.RunASegment(Segment s, StopConditions stopCond, Exception&amp;amp; exp)&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Microsoft Sans Serif" color="#800000" size="1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Microsoft Sans Serif" color="#800000" size="1"&gt;For more information, see Help and Support Center at &lt;/font&gt;&lt;a href="http://go.microsoft.com/fwlink/events.asp"&gt;&lt;font face="Microsoft Sans Serif" color="#800000" size="1"&gt;http://go.microsoft.com/fwlink/events.asp&lt;/font&gt;&lt;/a&gt;&lt;font face="Microsoft Sans Serif" color="#800000" size="1"&gt;.&lt;br&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Microsoft Sans Serif" color="#800000" size="1"&gt;&lt;font face="Trebuchet MS" color="#000000" size="2"&gt;As indicated in the event log text, the orchestration instance can be resumed (using HAT or WMI), and it will restart from its last persisted state.&amp;nbsp;This&amp;nbsp;goes&amp;nbsp;some way to&amp;nbsp;resolving the issues&amp;nbsp;from which the BizTalk 2004 model&amp;nbsp;suffers: the event log entry is more informative; and the orchestration state can be recovered much more easily. &lt;/font&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2"&gt;But we should not allow ourselves to think that these product changes mean that we can simplify to any great extent the way that we handle exceptions within our orchestrations. The fact that orchestration service instances can be resumed after an unanticipated and unhandled exception may be a saving grace in some circumstances, but it does not provide an automatic&amp;nbsp;panacea which can be relied upon to replace&amp;nbsp;specific exception handling within the orchestration:&lt;/font&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;for one thing, the resume mechanism is one that you do not want to be invoking routinely. It either requires use of the HAT tool by a human user, requiring appropriate alerting of operations personnel; or it needs to be&amp;nbsp;done automatically using WMI, and controlling BizTalk via WMI can be problematic if done in high volumes - the BizTalk WMI providers place considerable load on the Message Box, are not written to be highly scalable and may not behave correctly when multiple operations are performed concurrently (particularly those which change service instance states).  &lt;li&gt;although more exception context information is displayed in the event log entry than was the case with BizTalk Server 2004, using this context information in any automated recovery mechanism is not very easy.  &lt;li&gt;working out where the various persistence points in an orchestration are is not as easy as it might be. And it is possible for orchestration shapes executed after the last persistence point to have side effects: if these are not idempotent, automatic resumption from the last persistence point&amp;nbsp;may lead to incorrect system state.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;So in general, I would not advocate trying to incorporate this out-of-the-box exception handling functionality into your routine error handling mechanisms; you still need to analyse all the failure scenarios in your process carefully, catch all anticipatable exceptions in the appropriate places, and provide appropriate compensation blocks and explicit retry loops where necessary; the default exception handling functionality should remain a safety blanket which you ideally never use. Regarding any XLANG/s event log error as a symptom of a defect in your orchestration is, I think, a good mindset with which to approach the design of orchestration exception handling.&lt;/p&gt; &lt;p&gt;There is one exception scenario where BizTalk Server 2004 was deficient, and workarounds were very difficult, but BizTalk Server 2006 functionality is very much better: that is when an exception occurs during an attempt by BizTalk to execute a persistence point, for example if network problems cause connection errors when the BizTalk host instance running the orchestration tries to communicate with the Message Box. In BizTalk Server 2004, such exceptions caused an unhandled exception in the orchestration, and the orchestration service instance was rendered immediately Suspended (Not Resumable). In BizTalk Server 2006 the BTSNtSvc host process is now more savvy when it encounters difficulties communicating with the MessageBox: it logs an error to the event log but keeps&amp;nbsp;Active orchestration instances alive while it periodically retries the database call. If a retry succeeds, the orchestration instance proceeds on its way&amp;nbsp;completely unaware of&amp;nbsp;the temporary hiatus in MessageBox communication.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face="Microsoft Sans Serif" color="#800000" size="1"&gt;&amp;nbsp;&lt;/p&gt;&lt;/font&gt;&lt;img src="http://blogs.charteris.com/aggbug.aspx?PostID=159" width="1" height="1"&gt;</content><author><name>chrisdi</name><uri>http://blogs.charteris.com/members/chrisdi.aspx</uri></author><category term="BizTalk" scheme="http://blogs.charteris.com/blogs/chrisdi/archive/tags/BizTalk/default.aspx" /></entry><entry><title>InvalidOperation? I was only trying to open a connection...</title><link rel="alternate" type="text/html" href="http://blogs.charteris.com/blogs/chrisdi/archive/2006/12/12/InvalidOperation_3F00_-I-was-only-trying-to-open-a-connection_2E002E002E00_.aspx" /><id>http://blogs.charteris.com/blogs/chrisdi/archive/2006/12/12/InvalidOperation_3F00_-I-was-only-trying-to-open-a-connection_2E002E002E00_.aspx</id><published>2006-12-12T18:29:56Z</published><updated>2006-12-12T18:29:56Z</updated><content type="html">&lt;p&gt;I stumbled across&amp;nbsp;a little ADO.NET gotcha the other day...&lt;/p&gt; &lt;p&gt;By and large, ADO.NET's SQL client library presents a good, consistent exception interface when something goes wrong:&amp;nbsp;errors and warnings are&amp;nbsp;reported as instances of SqlException and there is lots of context wrapped up in&amp;nbsp;these exception objects enabling exception handling code to distinguish between the various error conditions and implement a suitable failure or recovery strategy. This is fortunate, because lots of things can go wrong when calling into a database across a network connection, many of them being transient issues which call for retry strategies of one sort or another. So a common pattern in a data access layer involves catching and mapping SqlException instances to a specific exception handling implementation, following every call to the database:&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;try&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;{&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp; using (SqlConnection connection = ...)&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp; {&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;...&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;connection.Open();&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ... use the connection to call the database&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;}&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;catch (SqlException sqlException)&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;{&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp; HandleException(sqlException);&amp;nbsp;&amp;nbsp; // Application-specific mapping function&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;}&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;This is so much nicer than using APIs which have a list as long as your arm of different exception types which might be thrown depending on the error condition.&lt;/p&gt; &lt;p&gt;I was disappointed to discover that ADO.NET (1.1) is not perfect in this respect either.&amp;nbsp;A system under heavy load suddenly threw this exception at us,&amp;nbsp;neatly circumventing all our&amp;nbsp;carefully crafted database exception handling and requiring operator intervention for a condition which was transient and eminently suitable for an automated approach to recovery:&lt;/p&gt; &lt;p&gt;&lt;font face="Arial" color="#800000" size="1"&gt;System.InvalidOperationException: Timeout expired.&amp;nbsp; The timeout period elapsed prior to obtaining a connection from the pool.&amp;nbsp; This may have occurred because all pooled connections were in use and max pool size was reached.&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Arial" color="#800000" size="1"&gt;&amp;nbsp;&amp;nbsp; at System.Data.SqlClient.SqlConnectionPoolManager.GetPooledConnection(SqlConnectionString options, Boolean&amp;amp; isInTransaction)&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Arial" color="#800000" size="1"&gt;&amp;nbsp;&amp;nbsp; at System.Data.SqlClient.SqlConnection.Open()&lt;/font&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face="Arial" color="#800000" size="1"&gt;&amp;nbsp;&amp;nbsp; at ... (our code)&lt;/font&gt;&lt;/p&gt; &lt;p&gt;What made this even more disappointing was that a brief&amp;nbsp;foray with Reflector immediately showed that this was not the side effect of some catch-all exception handling which happened to throw InvalidOperation as a default choice, but must have been the result of a conscious decision to throw InvalidOperation for a very specific timeout condition (the exception thrown is even instantiated in its own dedicated utility method&amp;nbsp;&lt;font face="Courier New"&gt;System.Data.SqlClient.SQL.PooledOpenTimeout()&lt;/font&gt;). I would love to know what the thought process behind that design decision was. InvalidOperation is supposed to mean that the method call was invalid for the current state of the object on which it is made. Er... excuse me... I just called Open() an a freshly instantiated SqlConnection. And the &lt;font face="Arial" size="1"&gt;&lt;font color="#800000"&gt;&lt;font face="Courier New" color="#000000" size="2"&gt;GetPooledConnection&lt;/font&gt; &lt;/font&gt;&lt;/font&gt;method where it was actually thrown is &lt;font face="Courier New"&gt;static&lt;/font&gt;.&amp;nbsp;&amp;nbsp;&lt;/p&gt; &lt;p&gt;InvalidOperationException unfortunately provides exactly zero additional context data beyond what it inherits from its base types System.SystemException and System.Exception, which leaves us having to parse the Message property to distinguish this particular timeout condition from any other InvalidOperationException&amp;nbsp;which we might&amp;nbsp;catch. Not very nice.&amp;nbsp;&lt;/p&gt; &lt;p&gt;Thankfully, I see that the implementation behind SqlConnection.Open has changed substantially in Framework 2.0, and &lt;font face="Courier New"&gt;SqlConnectionPoolManager.GetPooledConnection()&lt;/font&gt; no longer exists, so let's hope this has been fixed.&lt;/p&gt;&lt;img src="http://blogs.charteris.com/aggbug.aspx?PostID=156" width="1" height="1"&gt;</content><author><name>chrisdi</name><uri>http://blogs.charteris.com/members/chrisdi.aspx</uri></author><category term="SQL Server" scheme="http://blogs.charteris.com/blogs/chrisdi/archive/tags/SQL+Server/default.aspx" /><category term="ADO.NET" scheme="http://blogs.charteris.com/blogs/chrisdi/archive/tags/ADO.NET/default.aspx" /></entry><entry><title>SQL Server: The effect of collation on CHECKSUM</title><link rel="alternate" type="text/html" href="http://blogs.charteris.com/blogs/chrisdi/archive/2006/10/31/SQL-Server_3A00_-The-effect-of-collation-on-CHECKSUM.aspx" /><id>http://blogs.charteris.com/blogs/chrisdi/archive/2006/10/31/SQL-Server_3A00_-The-effect-of-collation-on-CHECKSUM.aspx</id><published>2006-10-31T11:45:06Z</published><updated>2006-10-31T11:45:06Z</updated><content type="html">&lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;span&gt;&lt;font face="Trebuchet MS" size="2"&gt;Diagnosing a bug in a SQL Server stored procedure recently I unearthed an interesting ‘feature’ of the CHECKSUM function which I couldn't find documented elsewhere.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;span&gt;&lt;font face="Trebuchet MS" size="2"&gt;The stored procedure received some data as Unicode string arguments, and after some validation and processing stored it in tables defined with VARCHAR columns. (Yes, I know this sounds like a less than optimal design, but this was an application integration task and both the source data and the target database schema were defined by other applications). &lt;span&gt;&lt;font face="Trebuchet MS" size="2"&gt;The problem was arising in another stored procedure which used the data from the tables, involving a join&amp;nbsp;on a hash column which the first stored procedure had calculated&amp;nbsp;using CHECKSUM. This join&amp;nbsp;had the expected behaviour in most environments, but failed to&amp;nbsp;generate any of the expected rows when executed on a particular SQL Server instance.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;/font&gt;&lt;/span&gt; &lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;span&gt;&lt;font face="Trebuchet MS" size="2"&gt;The cause of the problem was eventually tracked down to the fact that the stored procedure code was not being completely fastidious about conversions between VARCHAR and NVARCHAR in the parts of the code where the CHECKSUM hash was being generated. On most SQL instances, this was not a problem since &lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;CHECKSUM(&amp;lt;VARCHAR&amp;gt;) yielded exactly the same value as CHECKSUM(&amp;lt;NVARCHAR&amp;gt;) for the string values concerned. &lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font face="Trebuchet MS" size="2"&gt;It transpired, however, that for certain collations this relationship does not hold true, and the SQL Server instance where the problem emerged happened to have a default collation which exposed this difference.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin:0cm 0cm 6pt;"&gt;&lt;span&gt;&lt;font face="Trebuchet MS" size="2"&gt;The following query evolved during diagnosis of the problem, and illustrates where the potential pitfalls lie when using&amp;nbsp;CHECKSUM in T-SQL code which may need to&amp;nbsp;be portable between SQL Server instances with potentially differing collations:&lt;/font&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New';mso-bidi-font-family:vrinda;mso-ansi-language:en-us;mso-fareast-language:en-us;mso-bidi-language:#ac45;mso-no-proof:yes;"&gt;set&lt;/span&gt;&lt;span style="font-size:10pt;font-family:'Courier New';mso-bidi-font-family:vrinda;mso-ansi-language:en-us;mso-fareast-language:en-us;mso-bidi-language:#ac45;mso-no-proof:yes;"&gt; nocount &lt;span style="color:blue;"&gt;on&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New';mso-bidi-font-family:vrinda;mso-ansi-language:en-us;mso-fareast-language:en-us;mso-bidi-language:#ac45;mso-no-proof:yes;"&gt;create&lt;/span&gt;&lt;span style="font-size:10pt;font-family:'Courier New';mso-bidi-font-family:vrinda;mso-ansi-language:en-us;mso-fareast-language:en-us;mso-bidi-language:#ac45;mso-no-proof:yes;"&gt; &lt;span style="color:blue;"&gt;table&lt;/span&gt; #collations &lt;span style="color:gray;"&gt;(&lt;/span&gt;name &lt;span style="color:blue;"&gt;sysname&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt; sql &lt;span style="color:blue;"&gt;nvarchar&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;1000&lt;span style="color:gray;"&gt;))&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New';mso-bidi-font-family:vrinda;mso-ansi-language:en-us;mso-fareast-language:en-us;mso-bidi-language:#ac45;mso-no-proof:yes;"&gt;create&lt;/span&gt;&lt;span style="font-size:10pt;font-family:'Courier New';mso-bidi-font-family:vrinda;mso-ansi-language:en-us;mso-fareast-language:en-us;mso-bidi-language:#ac45;mso-no-proof:yes;"&gt; &lt;span style="color:blue;"&gt;table&lt;/span&gt; #compare &lt;span style="color:gray;"&gt;(&lt;/span&gt;collationName &lt;span style="color:blue;"&gt;sysname&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt; vcharHash &lt;span style="color:blue;"&gt;int&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt; nvcharHash &lt;span style="color:blue;"&gt;int&lt;/span&gt;&lt;span style="color:gray;"&gt;)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New';mso-bidi-font-family:vrinda;mso-ansi-language:en-us;mso-fareast-language:en-us;mso-bidi-language:#ac45;mso-no-proof:yes;"&gt;insert&lt;/span&gt;&lt;span style="font-size:10pt;font-family:'Courier New';mso-bidi-font-family:vrinda;mso-ansi-language:en-us;mso-fareast-language:en-us;mso-bidi-language:#ac45;mso-no-proof:yes;"&gt; #collations&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New';mso-bidi-font-family:vrinda;mso-ansi-language:en-us;mso-fareast-language:en-us;mso-bidi-language:#ac45;mso-no-proof:yes;"&gt;SELECT&lt;/span&gt;&lt;span style="font-size:10pt;font-family:'Courier New';mso-bidi-font-family:vrinda;mso-ansi-language:en-us;mso-fareast-language:en-us;mso-bidi-language:#ac45;mso-no-proof:yes;"&gt; &lt;/span&gt;&lt;/p&gt; &lt;blockquote&gt; &lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';mso-bidi-font-family:vrinda;mso-ansi-language:en-us;mso-fareast-language:en-us;mso-bidi-language:#ac45;mso-no-proof:yes;"&gt;name&lt;span style="color:gray;"&gt;,&lt;/span&gt; &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';mso-bidi-font-family:vrinda;mso-ansi-language:en-us;mso-fareast-language:en-us;mso-bidi-language:#ac45;mso-no-proof:yes;"&gt;&lt;span style="color:red;"&gt;'SELECT '''&lt;/span&gt; &lt;span style="color:gray;"&gt;+&lt;/span&gt; name &lt;span style="color:gray;"&gt;+&lt;/span&gt; &lt;span style="color:red;"&gt;''', CHECKSUM(''1234'' COLLATE '&lt;/span&gt; &lt;span style="color:gray;"&gt;+&lt;/span&gt; name &lt;span style="color:gray;"&gt;+&lt;/span&gt; &lt;span style="color:red;"&gt;'), CHECKSUM(N''1234'' COLLATE '&lt;/span&gt; &lt;span style="color:gray;"&gt;+&lt;/span&gt; name&amp;nbsp;+ &lt;span style="color:red;"&gt;')'&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New';mso-bidi-font-family:vrinda;mso-ansi-language:en-us;mso-fareast-language:en-us;mso-bidi-language:#ac45;mso-no-proof:yes;"&gt;FROM&lt;/span&gt;&lt;span style="font-size:10pt;font-family:'Courier New';mso-bidi-font-family:vrinda;mso-ansi-language:en-us;mso-fareast-language:en-us;mso-bidi-language:#ac45;mso-no-proof:yes;"&gt; &lt;span style="color:gray;"&gt;::&lt;/span&gt;fn_helpcollations&lt;span style="color:gray;"&gt;()&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;span style="font-size:10pt;color:gray;font-family:'Courier New';mso-bidi-font-family:vrinda;mso-ansi-language:en-us;mso-fareast-language:en-us;mso-bidi-language:#ac45;mso-no-proof:yes;"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New';mso-bidi-font-family:vrinda;mso-ansi-language:en-us;mso-fareast-language:en-us;mso-bidi-language:#ac45;mso-no-proof:yes;"&gt;declare&lt;/span&gt;&lt;span style="font-size:10pt;font-family:'Courier New';mso-bidi-font-family:vrinda;mso-ansi-language:en-us;mso-fareast-language:en-us;mso-bidi-language:#ac45;mso-no-proof:yes;"&gt; c &lt;span style="color:blue;"&gt;cursor&lt;/span&gt; &lt;span style="color:blue;"&gt;for&lt;/span&gt; &lt;span style="color:blue;"&gt;select&lt;/span&gt; sql &lt;span style="color:blue;"&gt;from&lt;/span&gt; #collations&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New';mso-bidi-font-family:vrinda;mso-ansi-language:en-us;mso-fareast-language:en-us;mso-bidi-language:#ac45;mso-no-proof:yes;"&gt; &lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New';mso-bidi-font-family:vrinda;mso-ansi-language:en-us;mso-fareast-language:en-us;mso-bidi-language:#ac45;mso-no-proof:yes;"&gt;declare&lt;/span&gt;&lt;span style="font-size:10pt;font-family:'Courier New';mso-bidi-font-family:vrinda;mso-ansi-language:en-us;mso-fareast-language:en-us;mso-bidi-language:#ac45;mso-no-proof:yes;"&gt; @sql &lt;span style="color:blue;"&gt;nvarchar&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;1000&lt;span style="color:gray;"&gt;)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&amp;nbsp;&lt;/p&gt; &lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;open&lt;/span&gt;&lt;span style="font-size:10pt;font-family:'Courier New';mso-bidi-font-family:vrinda;mso-ansi-language:en-us;mso-fareast-language:en-us;mso-bidi-language:#ac45;mso-no-proof:yes;"&gt; c&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New';mso-bidi-font-family:vrinda;mso-ansi-language:en-us;mso-fareast-language:en-us;mso-bidi-language:#ac45;mso-no-proof:yes;"&gt;fetch&lt;/span&gt;&lt;span style="font-size:10pt;font-family:'Courier New';mso-bidi-font-family:vrinda;mso-ansi-language:en-us;mso-fareast-language:en-us;mso-bidi-language:#ac45;mso-no-proof:yes;"&gt; next &lt;span style="color:blue;"&gt;from&lt;/span&gt; c &lt;span style="color:blue;"&gt;into&lt;/span&gt; @sql&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New';mso-bidi-font-family:vrinda;mso-ansi-language:en-us;mso-fareast-language:en-us;mso-bidi-language:#ac45;mso-no-proof:yes;"&gt;while&lt;/span&gt;&lt;span style="font-size:10pt;font-family:'Courier New';mso-bidi-font-family:vrinda;mso-ansi-language:en-us;mso-fareast-language:en-us;mso-bidi-language:#ac45;mso-no-proof:yes;"&gt; &lt;span style="color:fuchsia;"&gt;@@FETCH_STATUS&lt;/span&gt; &lt;span style="color:gray;"&gt;=&lt;/span&gt; 0&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New';mso-bidi-font-family:vrinda;mso-ansi-language:en-us;mso-fareast-language:en-us;mso-bidi-language:#ac45;mso-no-proof:yes;"&gt;begin&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';mso-bidi-font-family:vrinda;mso-ansi-language:en-us;mso-fareast-language:en-us;mso-bidi-language:#ac45;mso-no-proof:yes;"&gt;&lt;span style="mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;-- exclude Hindi collations from consideration as they can only apply to NVARCHAR values&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';mso-bidi-font-family:vrinda;mso-ansi-language:en-us;mso-fareast-language:en-us;mso-bidi-language:#ac45;mso-no-proof:yes;"&gt;&lt;span style="mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt; &lt;span style="color:gray;"&gt;NOT&lt;/span&gt; @sql &lt;span style="color:gray;"&gt;like&lt;/span&gt; &lt;span style="color:red;"&gt;'SELECT ''Hindi_%'&lt;/span&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';mso-bidi-font-family:vrinda;mso-ansi-language:en-us;mso-fareast-language:en-us;mso-bidi-language:#ac45;mso-no-proof:yes;"&gt;&lt;span style="mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;begin&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';mso-bidi-font-family:vrinda;mso-ansi-language:en-us;mso-fareast-language:en-us;mso-bidi-language:#ac45;mso-no-proof:yes;"&gt;&lt;span style="mso-tab-count:2;"&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&gt;&lt;span style="color:blue;"&gt;insert&lt;/span&gt; #compare&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';mso-bidi-font-family:vrinda;mso-ansi-language:en-us;mso-fareast-language:en-us;mso-bidi-language:#ac45;mso-no-proof:yes;"&gt;&lt;span style="mso-tab-count:2;"&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&gt;&lt;span style="color:blue;"&gt;exec&lt;/span&gt; &lt;span style="color:maroon;"&gt;sp_executesql&lt;/span&gt; @sql&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';mso-bidi-font-family:vrinda;mso-ansi-language:en-us;mso-fareast-language:en-us;mso-bidi-language:#ac45;mso-no-proof:yes;"&gt;&lt;span style="mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;end&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';mso-bidi-font-family:vrinda;mso-ansi-language:en-us;mso-fareast-language:en-us;mso-bidi-language:#ac45;mso-no-proof:yes;"&gt;&lt;span style="mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;fetch&lt;/span&gt; next &lt;span style="color:blue;"&gt;from&lt;/span&gt; c &lt;span style="color:blue;"&gt;into&lt;/span&gt; @sql&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New';mso-bidi-font-family:vrinda;mso-ansi-language:en-us;mso-fareast-language:en-us;mso-bidi-language:#ac45;mso-no-proof:yes;"&gt;end&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New';mso-bidi-font-family:vrinda;mso-ansi-language:en-us;mso-fareast-language:en-us;mso-bidi-language:#ac45;mso-no-proof:yes;"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New';mso-bidi-font-family:vrinda;mso-ansi-language:en-us;mso-fareast-language:en-us;mso-bidi-language:#ac45;mso-no-proof:yes;"&gt;close&lt;/span&gt;&lt;span style="font-size:10pt;font-family:'Courier New';mso-bidi-font-family:vrinda;mso-ansi-language:en-us;mso-fareast-language:en-us;mso-bidi-language:#ac45;mso-no-proof:yes;"&gt; c&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New';mso-bidi-font-family:vrinda;mso-ansi-language:en-us;mso-fareast-language:en-us;mso-bidi-language:#ac45;mso-no-proof:yes;"&gt;deallocate&lt;/span&gt;&lt;span style="font-size:10pt;font-family:'Courier New';mso-bidi-font-family:vrinda;mso-ansi-language:en-us;mso-fareast-language:en-us;mso-bidi-language:#ac45;mso-no-proof:yes;"&gt; c&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';mso-bidi-font-family:vrinda;mso-ansi-language:en-us;mso-fareast-language:en-us;mso-bidi-language:#ac45;mso-no-proof:yes;"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New';mso-bidi-font-family:vrinda;mso-ansi-language:en-us;mso-fareast-language:en-us;mso-bidi-language:#ac45;mso-no-proof:yes;"&gt;print&lt;/span&gt;&lt;span style="font-size:10pt;font-family:'Courier New';mso-bidi-font-family:vrinda;mso-ansi-language:en-us;mso-fareast-language:en-us;mso-bidi-language:#ac45;mso-no-proof:yes;"&gt; &lt;span style="color:red;"&gt;'Collations where CHECKSUM(VARCHAR) differs from CHECKSUM(NVARCHAR)'&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;span style="font-size:10pt;color:blue;font-family:'Courier New';mso-bidi-font-family:vrinda;mso-ansi-language:en-us;mso-fareast-language:en-us;mso-bidi-language:#ac45;mso-no-proof:yes;"&gt;select&lt;/span&gt;&lt;span style="font-size:10pt;font-family:'Courier New';mso-bidi-font-family:vrinda;mso-ansi-language:en-us;mso-fareast-language:en-us;mso-bidi-language:#ac45;mso-no-proof:yes;"&gt; &lt;span style="color:gray;"&gt;*&lt;/span&gt; &lt;span style="color:blue;"&gt;from&lt;/span&gt; #compare &lt;span style="color:blue;"&gt;where&lt;/span&gt; vcharHash &lt;span style="color:gray;"&gt;!=&lt;/span&gt; nvcharHash&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;span style="font-size:10pt;font-family:'Courier New';mso-bidi-font-family:vrinda;mso-ansi-language:en-us;mso-fareast-language:en-us;mso-bidi-language:#ac45;mso-no-proof:yes;"&gt;&