<feed version="0.3" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns="http://purl.org/atom/ns#" xml:lang="en-US"><title>Buddhike's Weblog</title><link rel="alternate" type="text/html" href="http://blogs.thinktecture.com/buddhike/default.aspx" /><tagline type="text/html">{binary mind}</tagline><id>http://blogs.thinktecture.com/buddhike/default.aspx</id><author><url>http://blogs.thinktecture.com/buddhike/default.aspx</url></author><generator url="http://communityserver.org" version="1.1.0.50615">Community Server</generator><modified>2006-07-10T21:57:00Z</modified><entry><title>Kissing goodbye</title><link rel="alternate" type="text/html" href="http://blogs.thinktecture.com/buddhike/archive/2007/11/30/415042.aspx" /><id>ff4ed322-7612-4f43-9d7f-220c081c7cfd:415042</id><created>2007-11-30T11:21:00Z</created><content type="text/html" mode="escaped">&lt;p&gt;"Flames to dust... lovers to friends.... why do all good things come to an end... come to an end..." I just walked into my office humming one of my favorite Nelly Furtado songs and yes, one good (or best rather) thing in my life is about to end today. Although this is not a secret among my best friends, for all the others who've been reading this blog; today I'm retiring from &lt;a href="http://www.thinktecture.com"&gt;thinktecture&lt;/a&gt; family. &lt;img style="border-width: 0px;" alt="IMG_6804" src="http://geeksdiary.com/blogs/buddhike/WindowsLiveWriter/Kissinggoodbye_E8B9/IMG_6804_1.jpg" align="right" border="0" height="182" width="271"&gt;&amp;nbsp; &lt;/p&gt;
&lt;p&gt;It has been a wonderful ride through out the past three years or so and I'm truly gifted to work with a fantastic team like this. At thinktecture for the first time in my professional life I could find things I like to live with.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;However, just being a part of this rapidly changing world, lately I found that it's time for me to say good bye. So I'm leaving this virtual desk with lot of remarkable memories (And I only have good memories at tt &lt;img alt="Wink" src="http://messenger.msn.com/MMM2006-04-19_17.00/Resource/emoticons/wink_smile.gif"&gt;). &lt;/p&gt;
&lt;p&gt;I wish all the best to thinktecture and I'm certainly looking forward to seeing them in our future encounters very soon &lt;img alt="Wink" src="http://messenger.msn.com/MMM2006-04-19_17.00/Resource/emoticons/wink_smile.gif"&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img style="border-width: 0px;" alt="DSCN0025" src="http://geeksdiary.com/blogs/buddhike/WindowsLiveWriter/Kissinggoodbye_E8B9/DSCN0025_1.jpg" align="left" border="0" height="184" width="244"&gt; Last but definitely not least during the past few years I and my family made really good family friends and that will remain unchanged for the rest of our life.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;thinktecture Rocks!&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;/em&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;/em&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;/em&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;PS: About next stop in my professional career: I really hope that it deserves a dedicated post in my new blog (&lt;/em&gt;&lt;a href="http://geeksdiary.com"&gt;&lt;em&gt;http://geeksdiary.com&lt;/em&gt;&lt;/a&gt;&lt;em&gt;) as it's also going be full of escapades!!!&lt;/em&gt;&lt;/p&gt;&lt;img src="http://blogs.thinktecture.com/aggbug.aspx?PostID=415042" width="1" height="1"&gt;</content><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.thinktecture.com/buddhike/commentrss.aspx?PostID=415042</wfw:commentRss></entry><entry><title>Sniffing WCF applications in localhost</title><link rel="alternate" type="text/html" href="http://blogs.thinktecture.com/buddhike/archive/2007/11/20/415035.aspx" /><id>ff4ed322-7612-4f43-9d7f-220c081c7cfd:415035</id><created>2007-11-20T12:39:00Z</created><content type="text/html" mode="escaped">&lt;p&gt;WCF comes with handful of tracing and logging options. We can just enable it with a few lines in the config and we are good to go. Furthermore the SDK comes with a handy tool svctraceviewer.exe (for wimps &lt;img alt="Wink" src="http://messenger.msn.com/MMM2006-04-19_17.00/Resource/emoticons/wink_smile.gif"&gt;). &lt;/p&gt;
&lt;p&gt;However, out-of-the-box trace output gives us access to the data/activities only in the WCF world. For example, at some point we might want to look at the HTTP headers sent/received by the application or we might want to check out the transport level frames are written properly in a custom transport. Although this is quite easy to do with a tool like WireShark or Ethereal, it still wants us to deploy the client and the service applications in two different machines (either virtual or physical). &lt;/p&gt;
&lt;p&gt;I'm not done yet. In the end, under the covers, WCF also uses the well-known System.Net&amp;nbsp; APIs at the transport level. Therefore we can just use System.Net tracing settings to capture the wire level traffic right from the dev box.&lt;/p&gt;
&lt;p&gt;For example, to capture the http traffic we can use the following config settings.&lt;/p&gt;
&lt;div&gt;&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;system.diagnostics&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;
  &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;trace&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;autoflush&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="true"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;sources&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;
    &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;source&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;name&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="System.Net.HttpListener"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;
      &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;listeners&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;
        &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;add&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;name&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="FooNetTraceListener"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;listeners&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;
    &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;source&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;
  &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;sources&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;
  &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;sharedListeners&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;
    &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;add&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;name&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="FooNetTraceListener"&lt;/span&gt; 
    &lt;span style="color: rgb(255, 0, 0);"&gt;type&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="System.Diagnostics.TextWriterTraceListener"&lt;/span&gt; 
    &lt;span style="color: rgb(255, 0, 0);"&gt;initializeData&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="C:\dev\src\lab\wcf\WireLevelTracing\Logs\FooNetTrace.log"&lt;/span&gt; 
    &lt;span style="color: rgb(255, 0, 0);"&gt;traceOutputOptions&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="None"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;sharedListeners&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;
  &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;switches&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;
    &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;add&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;name&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="System.Net.HttpListener"&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;value&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="Verbose"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;switches&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;system.diagnostics&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt; If you want to capture the traffic for a built-in tcp transport or a custom transport using System.Net.Sockets API; change to trace source to System.Net.Sockets. &lt;/p&gt;&lt;img src="http://blogs.thinktecture.com/aggbug.aspx?PostID=415035" width="1" height="1"&gt;</content><slash:comments>1</slash:comments><wfw:commentRss>http://blogs.thinktecture.com/buddhike/commentrss.aspx?PostID=415035</wfw:commentRss></entry><entry><title>Releasing streams in message contracts</title><link rel="alternate" type="text/html" href="http://blogs.thinktecture.com/buddhike/archive/2007/09/06/414936.aspx" /><id>ff4ed322-7612-4f43-9d7f-220c081c7cfd:414936</id><created>2007-09-06T19:18:00Z</created><content type="text/html" mode="escaped">
&lt;p style="margin: 0in; font-family: Consolas; font-size: 10pt;"&gt;&lt;font face="Verdana"&gt;In a lot of WCF
streaming applications it's common to see a message contract like this.&lt;/font&gt;&lt;/p&gt;&lt;br&gt;

&lt;p style="margin: 0in; font-family: Consolas; font-size: 10pt;"&gt;[MessageContract]&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Consolas; font-size: 10pt;"&gt;public class
DownloadFileRequest&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Consolas; font-size: 10pt;"&gt;{&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Consolas; font-size: 10pt;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;[MessageHeader]&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Consolas; font-size: 10pt;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;private string filename;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Consolas; font-size: 10pt;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Consolas; font-size: 10pt;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;[MessageHeader]&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Consolas; font-size: 10pt;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;private int length;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Consolas; font-size: 10pt;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Consolas; font-size: 10pt;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;[MessageBodyMember]&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Consolas; font-size: 10pt;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;private Stream fileStream;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Consolas; font-size: 10pt;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Consolas; font-size: 10pt;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;public DownloadFileRequest()&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Consolas; font-size: 10pt;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Consolas; font-size: 10pt;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Consolas; font-size: 10pt;"&gt;}&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Consolas; font-size: 10pt;"&gt;&lt;font face="Verdana"&gt;This often brings
up the question "How can I release the stream when the streaming is
completed?". I just noticed a nice attempt by using a simple polling
mechanism in this article &lt;a href="http://www.codeproject.com/WCF/WCF_FileTransfer_Progress.asp"&gt;http://www.codeproject.com/WCF/WCF_FileTransfer_Progress.asp&lt;/a&gt;. But, there is much simpler and elegant way to do this. You simply have
to implement IDisposable interface in your message contract and clean up the
stream in the Dispose method.&lt;/font&gt;&lt;/p&gt;&lt;p style="margin: 0in; font-family: Consolas; font-size: 10pt;"&gt;&lt;br&gt;&lt;/p&gt;&lt;p style="margin: 0in; font-family: Consolas; font-size: 10pt;"&gt;[MessageContract]&lt;br&gt;public class DownloadFileRequest : IDisposable&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [MessageHeader]&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private string filename;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [MessageHeader]&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private int length;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [MessageBodyMember]&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private Stream fileStream;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public DownloadFileRequest()&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void Dispose()&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(fileStream != null)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fileStream.Dispose();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fileStream = null; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp; &lt;br&gt;}&lt;/p&gt;&lt;p style="margin: 0in; font-family: Consolas; font-size: 10pt;"&gt;&lt;br&gt;&lt;/p&gt;&lt;p style="margin: 0in; font-family: Consolas; font-size: 10pt;"&gt;

&lt;/p&gt;&lt;p style="margin: 0in; font-family: Consolas; font-size: 10pt;"&gt;&lt;font face="Verdana"&gt;Once the message has been fully streamed the dispatcher runtime will call Dispose in all input/output parameter objects used to construct the message.&lt;/font&gt;&lt;/p&gt;&lt;font face="Verdana"&gt;&lt;br&gt;&lt;/font&gt;

&lt;p style="margin: 0in; font-family: Consolas; font-size: 10pt;"&gt;&lt;font face="Verdana"&gt;In to a little bit of
internals like always ;). I looked up where exactly this happens in the
reflector.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Consolas; font-size: 10pt;"&gt;&lt;font face="Verdana"&gt;As far as I can
understand this work is done in MessageRpc.DisposeParameterList method.&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Consolas; font-size: 10pt;"&gt;&lt;span style="color: rgb(16, 0, 160);"&gt;private&lt;/span&gt; &lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Void"&gt;void&lt;/a&gt;
&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.ServiceModel:3.0.0.0:b77a5c561934e089/System.ServiceModel.Dispatcher.MessageRpc/DisposeParameterList%28Object%5b%5d%29"&gt;&lt;span style="font-weight: bold;"&gt;DisposeParameterList&lt;/span&gt;&lt;/a&gt;(&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Object"&gt;object&lt;/a&gt;[]
parameters)&lt;br&gt;
{&lt;br&gt;
&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.IDisposable"&gt;IDisposable&lt;/a&gt;
&lt;span style="font-weight: bold;"&gt;disposable&lt;/span&gt; = &lt;span style="color: maroon;"&gt;null&lt;/span&gt;;&lt;br&gt;
&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: rgb(16, 0, 160);"&gt;if&lt;/span&gt;
(&lt;span style="color: rgb(0, 96, 24);"&gt;parameters&lt;/span&gt; != &lt;span style="color: maroon;"&gt;null&lt;/span&gt;)&lt;br&gt;
&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;br&gt;
&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: rgb(16, 0, 160);"&gt;foreach&lt;/span&gt;
(&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Object"&gt;object&lt;/a&gt;
&lt;span style="font-weight: bold;"&gt;obj2&lt;/span&gt; &lt;span style="color: rgb(16, 0, 160);"&gt;in&lt;/span&gt;
&lt;span style="color: rgb(0, 96, 24);"&gt;parameters&lt;/span&gt;)&lt;br&gt;
&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;br&gt;
&lt;span style=""&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: rgb(0, 96, 24);"&gt;disposable&lt;/span&gt;
= &lt;span style="color: rgb(0, 96, 24);"&gt;obj2&lt;/span&gt; &lt;span style="color: rgb(16, 0, 160);"&gt;as&lt;/span&gt;
&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.IDisposable"&gt;IDisposable&lt;/a&gt;;&lt;br&gt;
&lt;span style=""&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: rgb(16, 0, 160);"&gt;if&lt;/span&gt;
(&lt;span style="color: rgb(0, 96, 24);"&gt;disposable&lt;/span&gt; != &lt;span style="color: maroon;"&gt;null&lt;/span&gt;)&lt;br&gt;
&lt;span style=""&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;br&gt;
&lt;span style=""&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; &lt;/span&gt;&lt;span style="color: rgb(16, 0, 160);"&gt;try&lt;/span&gt;&lt;br&gt;
&lt;span style=""&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; &lt;/span&gt;{&lt;br&gt;
&lt;span style=""&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;/span&gt;&lt;span style="color: rgb(0, 96, 24);"&gt;disposable&lt;/span&gt;.&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.IDisposable/Dispose%28%29"&gt;Dispose&lt;/a&gt;();&lt;br&gt;
&lt;span style=""&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; &lt;/span&gt;}&lt;br&gt;
&lt;span style=""&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; &lt;/span&gt;&lt;span style="color: rgb(16, 0, 160);"&gt;catch&lt;/span&gt;
(&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Exception"&gt;Exception&lt;/a&gt;
&lt;span style="font-weight: bold;"&gt;exception&lt;/span&gt;)&lt;br&gt;
&lt;span style=""&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; &lt;/span&gt;{&lt;br&gt;
&lt;span style=""&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;/span&gt;&lt;span style="color: rgb(16, 0, 160);"&gt;if&lt;/span&gt; (&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.ServiceModel:3.0.0.0:b77a5c561934e089/System.ServiceModel.DiagnosticUtility"&gt;DiagnosticUtility&lt;/a&gt;.&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.ServiceModel:3.0.0.0:b77a5c561934e089/System.ServiceModel.DiagnosticUtility/IsFatal%28System.Exception%29:Boolean"&gt;IsFatal&lt;/a&gt;(&lt;span style="color: rgb(0, 96, 24);"&gt;exception&lt;/span&gt;))&lt;br&gt;
&lt;span style=""&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;/span&gt;{&lt;br&gt;
&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: rgb(16, 0, 160);"&gt;throw&lt;/span&gt;;&lt;br&gt;
&lt;span style=""&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;/span&gt;}&lt;br&gt;
&lt;span style=""&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;/span&gt;&lt;span style="color: rgb(16, 0, 160);"&gt;this&lt;/span&gt;.&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.ServiceModel:3.0.0.0:b77a5c561934e089/System.ServiceModel.Dispatcher.MessageRpc/channelHandler:System.ServiceModel.Dispatcher.ChannelHandler"&gt;channelHandler&lt;/a&gt;.&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.ServiceModel:3.0.0.0:b77a5c561934e089/System.ServiceModel.Dispatcher.ChannelHandler/HandleError%28System.Exception%29:Boolean"&gt;HandleError&lt;/a&gt;(&lt;span style="color: rgb(0, 96, 24);"&gt;exception&lt;/span&gt;);&lt;br&gt;
&lt;span style=""&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; &lt;/span&gt;}&lt;br&gt;
&lt;span style=""&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;br&gt;
&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;br&gt;
&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;br&gt;
}&lt;/p&gt;&lt;p style="margin: 0in; font-family: Consolas; font-size: 10pt;"&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Consolas; font-size: 10pt;"&gt;&lt;font face="Verdana"&gt;So obviously if our
Message contract implements IDisposable it will be perfectly disposed by this
function.&lt;/font&gt;&lt;/p&gt;&lt;p style="margin: 0in; font-family: Consolas; font-size: 10pt;"&gt;&lt;font face="Verdana"&gt;&lt;br&gt;&lt;/font&gt;&lt;/p&gt;&lt;p style="margin: 0in; font-family: Consolas; font-size: 10pt;"&gt;&lt;font face="Verdana"&gt;Have fun!&lt;/font&gt;&lt;br&gt;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Consolas; font-size: 10pt;"&gt; &lt;/p&gt;&lt;img src="http://blogs.thinktecture.com/aggbug.aspx?PostID=414936" width="1" height="1"&gt;</content><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.thinktecture.com/buddhike/commentrss.aspx?PostID=414936</wfw:commentRss></entry><entry><title>Some insights on calling sync proxy methods from multiple threads</title><link rel="alternate" type="text/html" href="http://blogs.thinktecture.com/buddhike/archive/2007/09/01/414926.aspx" /><id>ff4ed322-7612-4f43-9d7f-220c081c7cfd:414926</id><created>2007-09-01T06:15:00Z</created><content type="text/html" mode="escaped">&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;&lt;b&gt;Update: &lt;a href="http://blogs.catalystss.com/blogs/scott_seely"&gt;Scott Seely&lt;/a&gt; &lt;a href="http://blogs.catalystss.com/blogs/scott_seely/archive/2007/09/04/191.aspx"&gt;explained&lt;/a&gt; that this is by design.&amp;nbsp; So I'm changing the title in my post. Also if you want to do this, use async methods as he pointed out.&lt;/b&gt;&lt;br&gt;&lt;/p&gt;&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;&lt;br&gt;&lt;/p&gt;&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;Last night my friend
&lt;a href="http://www.thatindigogirl.com/"&gt;Michele&lt;/a&gt; pointed me an interesting thing on the WCF client side runtime.
Basically, she had a service method like as follows.&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;&lt;font face="Courier New" size="2"&gt;public void
SendMessage(string message)&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;&lt;font face="Courier New" size="2"&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;&lt;font face="Courier New" size="2"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;Console.WriteLine("SendMessage:
{0}", message);&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;&lt;font face="Courier New" size="2"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;MessageBox.Show(String.Format("Received message: '{0}'",
message));&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;&lt;font face="Courier New" size="2"&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;(We know, we know,
one should not display message boxes from a service method but here the idea
was basically blocking the thread that executes the service method
interactively.) &lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;Further more the
service was configured as PerCall/Multiple and was running on netTcp.&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;Then we tried to
call this service with an instance of svcutil generated proxy in several
threads simultaneously (see below).&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;&lt;font face="Courier New" size="2"&gt;&lt;span style=""&gt;&amp;nbsp;&lt;/span&gt;private void button1_Click(object sender,
EventArgs e)&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;&lt;font face="Courier New" size="2"&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;&lt;font face="Courier New" size="2"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;MethodInvoker m = new
MethodInvoker(CallService);&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;&lt;font face="Courier New" size="2"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;m.BeginInvoke(null, null);&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;&lt;font face="Courier New" size="2"&gt;&lt;span style=""&gt;&amp;nbsp;&lt;/span&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;&lt;font face="Courier New" size="2"&gt;&amp;nbsp;&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;&lt;font face="Courier New" size="2"&gt;&lt;span style=""&gt;&amp;nbsp;&lt;/span&gt;private void CallService()&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;&lt;font face="Courier New" size="2"&gt;&lt;span style=""&gt;&amp;nbsp;&lt;/span&gt;{&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;&lt;font face="Courier New" size="2"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;proxy.SendMessage(string.Format("Message {0}", ++counter));&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;&lt;font face="Courier New" size="2"&gt;&lt;span style=""&gt;&amp;nbsp;&lt;/span&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;When we ran client
and the service, we expected to see multiple messages boxes appearing in the
service as we click on the button1 in the client. In theory this should work
because, although we use a single tcp session, our service is configured for
PerCall and Multiple. So the message pump in the service side ChannelHandler
can use a new thread to pump the next message from the same tcp session and
dispatch it to a new service instance object while the previous message is
being processed.&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;However, things did
not workout the way we want.&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;When we
clicked the button, first message box appeared in the service. But subsequent
clicks did not do so until the first message box was closed (i.e. thread was released).
However, when all pending messages are displayed, everything started to work as
expected for the subsequent requests. &lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;Let the fun
begin!&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;:)&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;Out of curiosity I
got a snapshot of all threads while the client is blocked after the few very
first calls. Call stack of one blocking service call revealed quite a lot about
what's going on. The stack was like this (irrelevant frames and parameters are removed for simplicity
sake).&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;&lt;span style=""&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Consolas; font-size: 9pt;"&gt;[In a sleep, wait,
or join]&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Consolas; font-size: 9pt;"&gt;&lt;span style=""&gt;&lt;/span&gt;mscorlib.dll!System.Threading.WaitHandle.WaitOne() &lt;br&gt;&lt;/p&gt;&lt;p style="margin: 0in; font-family: Consolas; font-size: 9pt;"&gt;mscorlib.dll!System.Threading.WaitHandle.WaitOne()&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Consolas; font-size: 9pt;"&gt;&lt;span style=""&gt;&lt;/span&gt;System.ServiceModel.dll!System.ServiceModel.TimeoutHelper.WaitOne() &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Consolas; font-size: 9pt;"&gt;&lt;span style=""&gt;&lt;/span&gt;System.ServiceModel.dll!System.ServiceModel.Channels.ServiceChannel.CallOnceManager.SyncWaiter.Wait()&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Consolas; font-size: 9pt;"&gt;&lt;span style=""&gt;&lt;/span&gt;System.ServiceModel.dll!System.ServiceModel.Channels.ServiceChannel.CallOnceManager.CallOnce() &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Consolas; font-size: 9pt;"&gt;&lt;span style=""&gt;&lt;/span&gt;System.ServiceModel.dll!System.ServiceModel.Channels.ServiceChannel.EnsureOpened()&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Consolas; font-size: 9pt;"&gt;&lt;span style=""&gt;&lt;/span&gt;System.ServiceModel.dll!System.ServiceModel.Channels.ServiceChannel.Call()&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Consolas; font-size: 9pt;"&gt;&lt;span style=""&gt;&lt;/span&gt;System.ServiceModel.dll!System.ServiceModel.Channels.ServiceChannel.Call() &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Consolas; font-size: 9pt;"&gt;&lt;span style=""&gt;&lt;/span&gt;System.ServiceModel.dll!System.ServiceModel.Channels.ServiceChannelProxy.InvokeService() &amp;nbsp;&amp;nbsp;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Consolas; font-size: 9pt;"&gt;&lt;span style=""&gt;&lt;/span&gt;System.ServiceModel.dll!System.ServiceModel.Channels.ServiceChannelProxy.Invoke()&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Consolas; font-size: 9pt;"&gt;&lt;span style=""&gt;&lt;/span&gt;mscorlib.dll!System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke()&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;Aha! Interesting! On
the client side WCF internally uses ServiceChannel.Call to send/receive
messages from the service (regardless of whether you use svcutil generated
proxy or manual ChannelFactory and IClientChannel). So it seems like the call
is not going out of ServiceChannel.Call at all. It's blocking at a call to
EnsureOpened method. Then I opened up Reflector hoping to find what's going on
in this method (Lutz, I thank you every time I use it :)).&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;Refelctor
demystified some of the interesting stuff WCF do in the client side. When we
call service methods, we simply call them with just a single line (we hardly
call Open explicitly).&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;Therefore WCF has
to make sure that the underlying channel is Open before sending the request.
This opening is just one time action. So internally WCF uses a thing called
CallOnceManager to make sure that&lt;span style=""&gt;&amp;nbsp;
&lt;/span&gt;actions like this are performed only once. &lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;The
ServiceChannel.EnsureOpened method calls the CallOnceManager which is
responsible for calling Channel.Open once to open the underlying channel (look
at the following code I extracted from Reflector).&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Consolas; font-size: 10pt;"&gt;&lt;span style="color: rgb(16, 0, 160);"&gt;internal&lt;/span&gt; &lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Void"&gt;void&lt;/a&gt;
&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.ServiceModel:3.0.0.0:b77a5c561934e089/System.ServiceModel.Channels.ServiceChannel.CallOnceManager/CallOnce%28System.TimeSpan,System.ServiceModel.Channels.ServiceChannel.CallOnceManager%29"&gt;&lt;span style="font-weight: bold;"&gt;CallOnce&lt;/span&gt;&lt;/a&gt;(&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.TimeSpan"&gt;TimeSpan&lt;/a&gt;
timeout, &lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.ServiceModel:3.0.0.0:b77a5c561934e089/System.ServiceModel.Channels.ServiceChannel"&gt;ServiceChannel&lt;/a&gt;.&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.ServiceModel:3.0.0.0:b77a5c561934e089/System.ServiceModel.Channels.ServiceChannel.CallOnceManager"&gt;CallOnceManager&lt;/a&gt;
cascade)&lt;br&gt;
{&lt;br&gt;
&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.ServiceModel:3.0.0.0:b77a5c561934e089/System.ServiceModel.Channels.ServiceChannel.CallOnceManager.SyncWaiter"&gt;SyncWaiter&lt;/a&gt;
&lt;span style="font-weight: bold;"&gt;item&lt;/span&gt; = &lt;span style="color: maroon;"&gt;null&lt;/span&gt;;&lt;br&gt;
&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Boolean"&gt;bool&lt;/a&gt;
&lt;span style="font-weight: bold;"&gt;flag&lt;/span&gt; = &lt;span style="color: maroon;"&gt;false&lt;/span&gt;;&lt;br&gt;
&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: rgb(16, 0, 160);"&gt;if&lt;/span&gt;
(&lt;span style="color: rgb(16, 0, 160);"&gt;this&lt;/span&gt;.&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.ServiceModel:3.0.0.0:b77a5c561934e089/System.ServiceModel.Channels.ServiceChannel.CallOnceManager/queue:System.Collections.Generic.Queue%3cSystem.ServiceModel.Channels.ServiceChannel.CallOnceManager.IWaiter%3e"&gt;queue&lt;/a&gt;
!= &lt;span style="color: maroon;"&gt;null&lt;/span&gt;)&lt;br&gt;
&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;br&gt;
&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: rgb(16, 0, 160);"&gt;lock&lt;/span&gt;
(&lt;span style="color: rgb(16, 0, 160);"&gt;this&lt;/span&gt;.&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.ServiceModel:3.0.0.0:b77a5c561934e089/System.ServiceModel.Channels.ServiceChannel.CallOnceManager/property:ThisLock:Object"&gt;ThisLock&lt;/a&gt;)&lt;br&gt;
&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;br&gt;
&lt;span style=""&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: rgb(16, 0, 160);"&gt;if&lt;/span&gt;
(&lt;span style="color: rgb(16, 0, 160);"&gt;this&lt;/span&gt;.&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.ServiceModel:3.0.0.0:b77a5c561934e089/System.ServiceModel.Channels.ServiceChannel.CallOnceManager/queue:System.Collections.Generic.Queue%3cSystem.ServiceModel.Channels.ServiceChannel.CallOnceManager.IWaiter%3e"&gt;queue&lt;/a&gt;
!= &lt;span style="color: maroon;"&gt;null&lt;/span&gt;)&lt;br&gt;
&lt;span style=""&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;br&gt;
&lt;span style=""&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; &lt;/span&gt;&lt;span style="color: rgb(16, 0, 160);"&gt;if&lt;/span&gt;
(&lt;span style="color: rgb(16, 0, 160);"&gt;this&lt;/span&gt;.&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.ServiceModel:3.0.0.0:b77a5c561934e089/System.ServiceModel.Channels.ServiceChannel.CallOnceManager/isFirst:Boolean"&gt;isFirst&lt;/a&gt;)&lt;br&gt;
&lt;span style=""&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; &lt;/span&gt;{&lt;br&gt;
&lt;span style=""&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;/span&gt;&lt;span style="color: rgb(0, 96, 24);"&gt;flag&lt;/span&gt; = &lt;span style="color: maroon;"&gt;true&lt;/span&gt;;&lt;br&gt;
&lt;span style=""&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;/span&gt;&lt;span style="color: rgb(16, 0, 160);"&gt;this&lt;/span&gt;.&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.ServiceModel:3.0.0.0:b77a5c561934e089/System.ServiceModel.Channels.ServiceChannel.CallOnceManager/isFirst:Boolean"&gt;isFirst&lt;/a&gt;
= &lt;span style="color: maroon;"&gt;false&lt;/span&gt;;&lt;br&gt;
&lt;span style=""&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; &lt;/span&gt;}&lt;br&gt;
&lt;span style=""&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; &lt;/span&gt;&lt;span style="color: rgb(16, 0, 160);"&gt;else&lt;/span&gt;&lt;br&gt;
&lt;span style=""&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; &lt;/span&gt;{&lt;br&gt;
&lt;span style=""&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;/span&gt;&lt;span style="color: rgb(0, 96, 24);"&gt;item&lt;/span&gt; = &lt;span style="color: rgb(16, 0, 160);"&gt;new&lt;/span&gt; &lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.ServiceModel:3.0.0.0:b77a5c561934e089/System.ServiceModel.Channels.ServiceChannel.CallOnceManager.SyncWaiter/.ctor%28System.ServiceModel.Channels.ServiceChannel.CallOnceManager%29"&gt;SyncWaiter&lt;/a&gt;(&lt;span style="color: rgb(16, 0, 160);"&gt;this&lt;/span&gt;);&lt;br&gt;
&lt;span style=""&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;/span&gt;&lt;span style="color: rgb(16, 0, 160);"&gt;this&lt;/span&gt;.&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.ServiceModel:3.0.0.0:b77a5c561934e089/System.ServiceModel.Channels.ServiceChannel.CallOnceManager/queue:System.Collections.Generic.Queue%3cSystem.ServiceModel.Channels.ServiceChannel.CallOnceManager.IWaiter%3e"&gt;queue&lt;/a&gt;.&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System:2.0.0.0:b77a5c561934e089/System.Collections.Generic.Queue%3c%3e/Enqueue%28%3c%210%3e%29"&gt;Enqueue&lt;/a&gt;(&lt;span style="color: rgb(0, 96, 24);"&gt;item&lt;/span&gt;);&lt;br&gt;
&lt;span style=""&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; &lt;/span&gt;}&lt;br&gt;
&lt;span style=""&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;br&gt;
&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;br&gt;
&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;br&gt;
&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.ServiceModel:3.0.0.0:b77a5c561934e089/System.ServiceModel.Channels.ServiceChannel.CallOnceManager/SignalNextIfNonNull%28System.ServiceModel.Channels.ServiceChannel.CallOnceManager%29"&gt;SignalNextIfNonNull&lt;/a&gt;(&lt;span style="color: rgb(0, 96, 24);"&gt;cascade&lt;/span&gt;);&lt;br&gt;
&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: rgb(16, 0, 160);"&gt;if&lt;/span&gt;
(&lt;span style="color: rgb(0, 96, 24);"&gt;flag&lt;/span&gt;)&lt;br&gt;
&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;br&gt;
&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Boolean"&gt;bool&lt;/a&gt;
&lt;span style="font-weight: bold;"&gt;flag2&lt;/span&gt; = &lt;span style="color: maroon;"&gt;true&lt;/span&gt;;&lt;br&gt;
&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: rgb(16, 0, 160);"&gt;try&lt;/span&gt;&lt;br&gt;
&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;br&gt;
&lt;span style=""&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: rgb(16, 0, 160);"&gt;this&lt;/span&gt;.&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.ServiceModel:3.0.0.0:b77a5c561934e089/System.ServiceModel.Channels.ServiceChannel.CallOnceManager/callOnce:System.ServiceModel.Channels.ServiceChannel.ICallOnce"&gt;callOnce&lt;/a&gt;.&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.ServiceModel:3.0.0.0:b77a5c561934e089/System.ServiceModel.Channels.ServiceChannel.ICallOnce/Call%28System.ServiceModel.Channels.ServiceChannel,System.TimeSpan%29"&gt;Call&lt;/a&gt;(&lt;span style="color: rgb(16, 0, 160);"&gt;this&lt;/span&gt;.&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.ServiceModel:3.0.0.0:b77a5c561934e089/System.ServiceModel.Channels.ServiceChannel.CallOnceManager/channel:System.ServiceModel.Channels.ServiceChannel"&gt;channel&lt;/a&gt;,
&lt;span style="color: rgb(0, 96, 24);"&gt;timeout&lt;/span&gt;);&lt;br&gt;
&lt;span style=""&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: rgb(0, 96, 24);"&gt;flag2&lt;/span&gt;
= &lt;span style="color: maroon;"&gt;false&lt;/span&gt;;&lt;br&gt;
&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;br&gt;
&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: rgb(16, 0, 160);"&gt;finally&lt;/span&gt;&lt;br&gt;
&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;br&gt;
&lt;span style=""&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: rgb(16, 0, 160);"&gt;if&lt;/span&gt;
(&lt;span style="color: rgb(0, 96, 24);"&gt;flag2&lt;/span&gt;)&lt;br&gt;
&lt;span style=""&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;br&gt;
&lt;span style=""&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; &lt;/span&gt;&lt;span style="color: rgb(16, 0, 160);"&gt;this&lt;/span&gt;.&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.ServiceModel:3.0.0.0:b77a5c561934e089/System.ServiceModel.Channels.ServiceChannel.CallOnceManager/SignalNext%28%29"&gt;SignalNext&lt;/a&gt;();&lt;br&gt;
&lt;span style=""&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;br&gt;
&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;br&gt;
&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;br&gt;
&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: rgb(16, 0, 160);"&gt;else&lt;/span&gt;
&lt;span style="color: rgb(16, 0, 160);"&gt;if&lt;/span&gt; (&lt;span style="color: rgb(0, 96, 24);"&gt;item&lt;/span&gt;
!= &lt;span style="color: maroon;"&gt;null&lt;/span&gt;)&lt;br&gt;
&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;br&gt;
&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: rgb(0, 96, 24);"&gt;item&lt;/span&gt;.&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.ServiceModel:3.0.0.0:b77a5c561934e089/System.ServiceModel.Channels.ServiceChannel.CallOnceManager.SyncWaiter/Wait%28System.TimeSpan%29:Boolean"&gt;Wait&lt;/a&gt;(&lt;span style="color: rgb(0, 96, 24);"&gt;timeout&lt;/span&gt;);&lt;br&gt;
&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;br&gt;
}&lt;br&gt;
&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;CallOnceManager
services the simultaneous requests trying to use it for the first time in a
FIFO fashion using a queue. This queue is initialized in the ctor. When the
CallOnce is invoked it checks whether this queue is available and if
"yes", it checks whether this call is the first one. If it's NOT, a
waitable object is created and placed in the queue and then CallOnce method
blocks on this newly created waitable object.&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;So out of several
simultaneous *first* calls to CallOnce the one that wins open the channel and
returns back to the ServiceChannel.Call frame. After doing some more work it
finally uses this newly opened channel to send the message. When the reply is
returned, it calls CallOnceManager.SingnalIfNotNull method which in turn calls
the CallOnceManager.SignalNext method to signal the next waitable object in the
queue. When it's signaled the relevant CallOnce call that was waiting on it
gets released and the next request is sent to the service.&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;So in our case first
request did not return until we closed the message box. So the subsequent
service method calls were hanging at the CallOnceManager.CallOnce method.
Because first call has to return and call CallOnceManager.SingnalIfNotNull to
get one of the waiting calls released.&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;IMO, this is too
bad. This should essentially check whether the Open has called and if it has,
it should just flow without blocking.&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;On the second part
of the question. I was wondering why it was working after end all pending
calls. I opened up the SignalNext method and the answer was there.&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Consolas; font-size: 10pt;"&gt;&lt;span style="color: rgb(16, 0, 160);"&gt;internal&lt;/span&gt; &lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Void"&gt;void&lt;/a&gt;
&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.ServiceModel:3.0.0.0:b77a5c561934e089/System.ServiceModel.Channels.ServiceChannel.CallOnceManager/SignalNext%28%29"&gt;&lt;span style="font-weight: bold;"&gt;SignalNext&lt;/span&gt;&lt;/a&gt;()&lt;br&gt;
{&lt;br&gt;
&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: rgb(16, 0, 160);"&gt;if&lt;/span&gt;
(&lt;span style="color: rgb(16, 0, 160);"&gt;this&lt;/span&gt;.&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.ServiceModel:3.0.0.0:b77a5c561934e089/System.ServiceModel.Channels.ServiceChannel.CallOnceManager/queue:System.Collections.Generic.Queue%3cSystem.ServiceModel.Channels.ServiceChannel.CallOnceManager.IWaiter%3e"&gt;queue&lt;/a&gt;
!= &lt;span style="color: maroon;"&gt;null&lt;/span&gt;)&lt;br&gt;
&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;br&gt;
&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.ServiceModel:3.0.0.0:b77a5c561934e089/System.ServiceModel.Channels.ServiceChannel.CallOnceManager.IWaiter"&gt;IWaiter&lt;/a&gt;
&lt;span style="font-weight: bold;"&gt;state&lt;/span&gt; = &lt;span style="color: maroon;"&gt;null&lt;/span&gt;;&lt;br&gt;
&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: rgb(16, 0, 160);"&gt;lock&lt;/span&gt;
(&lt;span style="color: rgb(16, 0, 160);"&gt;this&lt;/span&gt;.&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.ServiceModel:3.0.0.0:b77a5c561934e089/System.ServiceModel.Channels.ServiceChannel.CallOnceManager/property:ThisLock:Object"&gt;ThisLock&lt;/a&gt;)&lt;br&gt;
&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;br&gt;
&lt;span style=""&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: rgb(16, 0, 160);"&gt;if&lt;/span&gt;
(&lt;span style="color: rgb(16, 0, 160);"&gt;this&lt;/span&gt;.&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.ServiceModel:3.0.0.0:b77a5c561934e089/System.ServiceModel.Channels.ServiceChannel.CallOnceManager/queue:System.Collections.Generic.Queue%3cSystem.ServiceModel.Channels.ServiceChannel.CallOnceManager.IWaiter%3e"&gt;queue&lt;/a&gt;
!= &lt;span style="color: maroon;"&gt;null&lt;/span&gt;)&lt;br&gt;
&lt;span style=""&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;br&gt;
&lt;span style=""&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; &lt;/span&gt;&lt;span style="color: rgb(16, 0, 160);"&gt;if&lt;/span&gt;
(&lt;span style="color: rgb(16, 0, 160);"&gt;this&lt;/span&gt;.&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.ServiceModel:3.0.0.0:b77a5c561934e089/System.ServiceModel.Channels.ServiceChannel.CallOnceManager/queue:System.Collections.Generic.Queue%3cSystem.ServiceModel.Channels.ServiceChannel.CallOnceManager.IWaiter%3e"&gt;queue&lt;/a&gt;.&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System:2.0.0.0:b77a5c561934e089/System.Collections.Generic.Queue%3cSystem.ServiceModel.Channels.ServiceChannel.CallOnceManager.IWaiter%3e/property:Count:Int32"&gt;Count&lt;/a&gt;
&amp;gt; &lt;span style="color: maroon;"&gt;0&lt;/span&gt;)&lt;br&gt;
&lt;span style=""&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; &lt;/span&gt;{&lt;br&gt;
&lt;span style=""&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;/span&gt;&lt;span style="color: rgb(0, 96, 24);"&gt;state&lt;/span&gt; = &lt;span style="color: rgb(16, 0, 160);"&gt;this&lt;/span&gt;.&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.ServiceModel:3.0.0.0:b77a5c561934e089/System.ServiceModel.Channels.ServiceChannel.CallOnceManager/queue:System.Collections.Generic.Queue%3cSystem.ServiceModel.Channels.ServiceChannel.CallOnceManager.IWaiter%3e"&gt;queue&lt;/a&gt;.&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System:2.0.0.0:b77a5c561934e089/System.Collections.Generic.Queue%3c%3e/Dequeue%28%29:%3c%210%3e"&gt;Dequeue&lt;/a&gt;();&lt;br&gt;
&lt;span style=""&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; &lt;/span&gt;}&lt;br&gt;
&lt;span style=""&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; &lt;/span&gt;&lt;span style="color: rgb(16, 0, 160);"&gt;else&lt;/span&gt;&lt;br&gt;
&lt;span style=""&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; &lt;/span&gt;{&lt;br&gt;
&lt;span style=""&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;/span&gt;&lt;span style="color: rgb(16, 0, 160);"&gt;this&lt;/span&gt;.&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.ServiceModel:3.0.0.0:b77a5c561934e089/System.ServiceModel.Channels.ServiceChannel.CallOnceManager/queue:System.Collections.Generic.Queue%3cSystem.ServiceModel.Channels.ServiceChannel.CallOnceManager.IWaiter%3e"&gt;queue&lt;/a&gt;
= &lt;span style="color: maroon;"&gt;null&lt;/span&gt;;&lt;br&gt;
&lt;span style=""&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; &lt;/span&gt;}&lt;br&gt;
&lt;span style=""&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;br&gt;
&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;br&gt;
&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: rgb(16, 0, 160);"&gt;if&lt;/span&gt;
(&lt;span style="color: rgb(0, 96, 24);"&gt;state&lt;/span&gt; != &lt;span style="color: maroon;"&gt;null&lt;/span&gt;)&lt;br&gt;
&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;br&gt;
&lt;span style=""&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;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.ServiceModel:3.0.0.0:b77a5c561934e089/System.ServiceModel.Channels.IOThreadScheduler"&gt;IOThreadScheduler&lt;/a&gt;.&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.ServiceModel:3.0.0.0:b77a5c561934e089/System.ServiceModel.Channels.IOThreadScheduler/ScheduleCallback%28System.Threading.WaitCallback,Object%29"&gt;ScheduleCallback&lt;/a&gt;(&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.ServiceModel:3.0.0.0:b77a5c561934e089/System.ServiceModel.Channels.ServiceChannel.CallOnceManager/signalWaiter:System.Threading.WaitCallback"&gt;signalWaiter&lt;/a&gt;,
&lt;span style="color: rgb(0, 96, 24);"&gt;state&lt;/span&gt;);&lt;br&gt;
&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;br&gt;
&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;br&gt;
}&lt;br&gt;
&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;When the SignalNext
is invoked it dequeues the next waitable object from the queue and signals
that. If the queue is empty (i.e. no more items striving to be first), it sets
the queue to null. Therefore the next call to CallOnceManager.CallOnce just
exists without doing anything because the queue is null.&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;IMO, this is a
little bug we have there ;). Dear team, please correct me if I'm missing
anything here or if this is by design please explain us why.&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;Meanwhile if
someone is trying to get over the problem I've also found a nice solution. The
CallOnceManager is used for automatic opening of channels. But if we call Open
explicitly in our code we can get rid of it (Look at how
ServiceChannel.EnsureOpened is called in ServiceChannel.Call method).&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Consolas; font-size: 10pt;"&gt;&lt;span style="color: rgb(16, 0, 160);"&gt;if&lt;/span&gt; (!&lt;span style="color: rgb(16, 0, 160);"&gt;this&lt;/span&gt;.&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.ServiceModel:3.0.0.0:b77a5c561934e089/System.ServiceModel.Channels.ServiceChannel/explicitlyOpened:Boolean"&gt;explicitlyOpened&lt;/a&gt;)&lt;br&gt;
{&lt;br&gt;
&lt;span style="color: rgb(16, 0, 160);"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;this&lt;/span&gt;.&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.ServiceModel:3.0.0.0:b77a5c561934e089/System.ServiceModel.Channels.ServiceChannel/EnsureDisplayUI%28%29"&gt;EnsureDisplayUI&lt;/a&gt;();&lt;br&gt;
&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: rgb(16, 0, 160);"&gt;this&lt;/span&gt;.&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.ServiceModel:3.0.0.0:b77a5c561934e089/System.ServiceModel.Channels.ServiceChannel/EnsureOpened%28System.TimeSpan%29"&gt;EnsureOpened&lt;/a&gt;(&lt;span style="color: rgb(0, 96, 24);"&gt;rpc&lt;/span&gt;.&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.ServiceModel:3.0.0.0:b77a5c561934e089/System.ServiceModel.Dispatcher.ProxyRpc/TimeoutHelper:System.ServiceModel.TimeoutHelper"&gt;TimeoutHelper&lt;/a&gt;.&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.ServiceModel:3.0.0.0:b77a5c561934e089/System.ServiceModel.TimeoutHelper/RemainingTime%28%29:System.TimeSpan"&gt;RemainingTime&lt;/a&gt;());&lt;br&gt;
}&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;&lt;span style=""&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;So we can turn on
this explicitlyOpened flag by calling Open *once* in our proxy or the channel
before invoking the method.&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p style="margin: 0in; font-family: Calibri; font-size: 11pt;"&gt;After all I started
to wonder why I did not spend little bit of more time to reflector the client
side runtime. There is a lot of fun out there as well!!! :)&lt;/p&gt;&lt;img src="http://blogs.thinktecture.com/aggbug.aspx?PostID=414926" width="1" height="1"&gt;</content><slash:comments>1</slash:comments><wfw:commentRss>http://blogs.thinktecture.com/buddhike/commentrss.aspx?PostID=414926</wfw:commentRss></entry><entry><title>IO Worker Threads - Performance Uncovered!</title><link rel="alternate" type="text/html" href="http://blogs.thinktecture.com/buddhike/archive/2007/08/05/414907.aspx" /><id>ff4ed322-7612-4f43-9d7f-220c081c7cfd:414907</id><created>2007-08-05T20:04:00Z</created><content type="text/html" mode="escaped">&lt;P&gt;Writing my last post about &lt;a href="http://blogs.thinktecture.com/buddhike/archive/2007/08/02/414902.aspx"&gt;WCF threading internals &lt;/A&gt;compelled me to reveal some of the tests I did sometime back. So today we are going to see how we can optimize the CPU utilization by using IO worker threads in CLR thread pool. &lt;BR&gt;We are talking about CPU. Therefore I wrote this simple method to be used in my tests which does some CPU intensive operations. Note that I don't do any IO at all, not even a Console.WriteLine() and this is *very* important to assure the accuracy of the results. &lt;BR&gt;In my CpuIntensiveMethod method I calculate the largest Fibonacci number that is below 100 and I run this calculation for int.MaxValue number of times (I will tell you why this number is preferred). &lt;/P&gt;
&lt;P&gt;&lt;PRE class=csharpcode&gt;&lt;SPAN class=kwrd&gt;static&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; CpuIntensiveMethod(&lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; testNumber)
{
    Stopwatch sw = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; Stopwatch();
    sw.Start();
                                    
    &lt;SPAN class=rem&gt;// Let's perform some math to keep our CPU busy here.&lt;/SPAN&gt;
    &lt;SPAN class=kwrd&gt;for&lt;/SPAN&gt; (&lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; i = 0; i &amp;lt; iterations; i++)
    {
        &lt;SPAN class=rem&gt;// Here we calculate the maximum Fibonacci number less than 100.&lt;/SPAN&gt;
        &lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; fn = 0;
        &lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; preFn = 0;

        &lt;SPAN class=kwrd&gt;while&lt;/SPAN&gt; (fn &amp;lt;= 100)
        {
            &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (fn &amp;lt; 2)
            {
                preFn = fn;
                fn++;
                &lt;SPAN class=kwrd&gt;continue&lt;/SPAN&gt;;
            }
            &lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; next = fn + preFn;
            preFn = fn;
            fn = next;
        }
    }

    sw.Stop();
    timings[testNumber, 0] = Thread.CurrentThread.ManagedThreadId;
    timings[testNumber, 1] = sw.ElapsedMilliseconds;
    timings[testNumber, 2] = sw.ElapsedTicks;
}&lt;/PRE&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;In addition to the Fibonacci number calculation I also measure the time taken for computation using a StopWatch (newly available utility since .NET 2.0 bits) and record results in a multi-dimensional array. The reason is again, I did not want to do any IO in this method and thus stayed away from even using Console.WriteLine(). BTW: Since there is no interactive way to see whether the method has completed; I monitored the CPU usage using ProcessExplorer (or TaskManager) and then printed the values in the multi-dimensional array once the CPU usage spike is normalized. &lt;/P&gt;
&lt;P&gt;In the first test, I simply ran CpuIntensiveMethod() in a single thread by simple calling this method from my main(). And the result was something like this. &lt;BR&gt;&lt;BR&gt;Test 0 ran in managed thread id 1: Milliseconds 32942 Ticks 117920861 &lt;/P&gt;
&lt;P&gt;During the run I could see my CPU was at 100% which was quite expected. So at this point someone might say, that this is the optimal result that I should ever expect. I would definitely agree if I just want to use a single processor in my entire life. Apparently when I ran this test in my dual core box the process was consuming only 50% of my total processing power. This is the reason why that this model does not fit into server applications world. In fact to put this story in to server applications perspective, let's assume that CpuIntensiveMethod is a function in a server application which invoked by multiple clients. So if we had only one thread, we would take ~33 seconds to service one client. And everyone else would not be taken care of until we are done with current one. &lt;/P&gt;
&lt;P&gt;So how can we solve this? We talked about one thread per client scenario in my last post (i.e. distributing work among multiple threads). Would it work? Sit back, we are about to try it now. To simulate this scenario I did my next test by running CpuIntensiveMethod method from several thread pool threads. But before talking about the test, let me tell you a little bit about some important CLR thread pool internals. CLR thread pool has worker threads (IO and non-IO) and a special thread called Gate thread. The gate thread is responsible for spinning up new worker threads. The algorithm it uses to determine when to spin a new thread is actually based on CPU utilization, GC frequency and worker queue size. So currently (to be more precise; as of last time I looked at win32threadpool.cpp back in 2006) this thread spins up for every 500ms. So if CpuIntensiveMethod method does not take too long it might get executed on the same thread pool thread and we would not be able to simulate concurrent clients as we originally intended. This is actually why I wanted to run my test int.MaxValue number of times (so, dear dev fellows, if you are running this code in a beefy box, please forgive me now :)). Getting back to our second test, I could successfully run my method in 10 thread pool threads concurrently and here are the numbers that I ended up with. &lt;BR&gt;&lt;BR&gt;Test 0 ran in managed thread id 3: Milliseconds 116489 Ticks 416980652&lt;BR&gt;Test 1 ran in managed thread id 4: Milliseconds 141677 Ticks 507140436&lt;BR&gt;Test 2 ran in managed thread id 5: Milliseconds 149974 Ticks 536840900&lt;BR&gt;Test 3 ran in managed thread id 6: Milliseconds 132707 Ticks 475034210&lt;BR&gt;Test 4 ran in managed thread id 7: Milliseconds 156416 Ticks 559901108&lt;BR&gt;Test 5 ran in managed thread id 8: Milliseconds 137661 Ticks 492765340&lt;BR&gt;Test 6 ran in managed thread id 9: Milliseconds 149318 Ticks 534491916&lt;BR&gt;Test 7 ran in managed thread id 10: Milliseconds 132840 Ticks 475507986&lt;BR&gt;Test 8 ran in managed thread id 11: Milliseconds 136866 Ticks 489920458&lt;BR&gt;Test 9 ran in managed thread id 12: Milliseconds 119222 Ticks 426763067&lt;BR&gt;&lt;/P&gt;
&lt;P&gt;Looks horrible! Isn't it??? Each thread has taken roughly more than 110 seconds for the computation. This is more than 3 times of the time taken by first test. But don't panic. In fact I was happy the fact that it produced results I wanted to see. The reason is simple. In this test I had 10 threads, each striving to take 100% CPU. This means more work for the scheduler. Switcing contexts, swapping pages etc. cause the delay we are seeing in the above table. Consequently this proves that having one thread per client does not help us achieving the best CPU utilization. &lt;/P&gt;
&lt;P&gt;In my final test I tried to service the same 10 concurrent calls that I had in the previous test but this time using thread pool's IOCP as shown below. &lt;/P&gt;
&lt;P&gt;&lt;PRE class=csharpcode&gt;&lt;SPAN class=kwrd&gt;for&lt;/SPAN&gt; (&lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; i = 0; i &amp;lt; 10; i++)
{
    &lt;SPAN class=kwrd&gt;unsafe&lt;/SPAN&gt;
    {
        Overlapped overlapped = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; Overlapped(0, 0, IntPtr.Zero, &lt;SPAN class=kwrd&gt;null&lt;/SPAN&gt;);
        NativeOverlapped* noverlapped = overlapped.Pack(&lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; IOCompletionCallback
            (IoThreadProc));
       noverlapped-&amp;gt;OffsetHigh = i;
       ThreadPool.UnsafeQueueNativeOverlapped(noverlapped);                
    }
}&lt;/PRE&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;Before I mention my results I must show you some nits in the above code snippet. Creating a NativeOverlapped structure is an expensive operation. Therefore you should try to create only one and reuse it if that fits bill (wanna be happy? Then listen. This is what WCF IOThreadScheduler does). However, in my case I wanted to have a way to pass the test number to CpuIntensiveMethod method. Therefore I used a simple hack by passing it in the OffsetHigh filed in the NativeOverlapped instance. Also you must make sure that you release the memory block held by NativeOverlapped structure by calling Overlapped.Free() function. Otherwise you will notice a rapidly growing working set and eventually your program will end up with an OOM exception (but here that's fine as this is a demo and I have only 10 instances of NativeOverlapped structure). OK, moving to the test results, this is what I got after running test 3. &lt;BR&gt;&lt;BR&gt;Test 0 ran in managed thread id 3: Milliseconds 33614 Ticks 120325281&lt;BR&gt;Test 1 ran in managed thread id 4: Milliseconds 35301 Ticks 126363625&lt;BR&gt;Test 2 ran in managed thread id 3: Milliseconds 32928 Ticks 117867839&lt;BR&gt;Test 3 ran in managed thread id 4: Milliseconds 34606 Ticks 123877189&lt;BR&gt;Test 4 ran in managed thread id 3: Milliseconds 33359 Ticks 119411572&lt;BR&gt;Test 5 ran in managed thread id 4: Milliseconds 34528 Ticks 123596836&lt;BR&gt;Test 6 ran in managed thread id 3: Milliseconds 33502 Ticks 119922606&lt;BR&gt;Test 7 ran in managed thread id 4: Milliseconds 34434 Ticks 123260605&lt;BR&gt;Test 8 ran in managed thread id 3: Milliseconds 34454 Ticks 123331465&lt;BR&gt;Test 9 ran in managed thread id 4: Milliseconds 34645 Ticks 124013520&lt;BR&gt;&lt;/P&gt;
&lt;P&gt;Pretty impressive! Isn't it??? Now each method has taken roughly around 33 seconds which was the same number we saw during test 1. So we were able to serve 10 concurrent calls while using our optimal processing power. Also notice that each method is executed on a thread with MT id either 3 or 4. What does this mean? When CLR thread pool creates its IOCP, it calculates the number of CPUs in the box and passes that value to NumberOfConcurrentThreads parameter of CreateIoCompletionPort function. So in my case, I ran these tests in a dual core box and thus IOCP only allowed only two threads to be active concurrently. That's why we see only manage thread ids 3 and 4. &lt;/P&gt;
&lt;P&gt;Concluding this post, I hope that these tests will help you to understand the optimizations that could be achieved by using IO worker threads. &lt;BR&gt;Wanna try out the tests yourself? &lt;a href="http://blogs.thinktecture.com/buddhike/files/iowpt.zip"&gt;Here are the sources. &lt;BR&gt;&lt;/A&gt;&lt;BR&gt;Have fun! &lt;/P&gt;&lt;img src="http://blogs.thinktecture.com/aggbug.aspx?PostID=414907" width="1" height="1"&gt;</content><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.thinktecture.com/buddhike/commentrss.aspx?PostID=414907</wfw:commentRss></entry><entry><title>WCF Threading Internals (Updated)</title><link rel="alternate" type="text/html" href="http://blogs.thinktecture.com/buddhike/archive/2007/08/02/414902.aspx" /><id>ff4ed322-7612-4f43-9d7f-220c081c7cfd:414902</id><created>2007-08-02T21:49:57Z</created><content type="text/html" mode="escaped">&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt"&gt;&lt;EM&gt;&lt;FONT style="BACKGROUND-COLOR: #ffffff" color=#ff0000&gt;Apologies! Last night I had accidently pressed the publish button without ticking the publish as a draft option. So those who have read this post already, sorry about the incomplete, poorly formatted text :(&lt;/FONT&gt;&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt"&gt;Along with its bunch of different features, WCF carries a lot of performance optimizations as well (you think I'm kidding? Then see it yourself &lt;A href="http://msdn2.microsoft.com/en-us/library/bb310550.aspx"&gt;http://msdn2.microsoft.com/en-us/library/bb310550.aspx&lt;/A&gt;). As a part of this, WCF has given a lot of thought about threading model that it uses behind the scenes. &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt"&gt;At this point you might probably think; &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt"&gt;&lt;EM&gt;"Well… I know it uses thread pool API. There is nothing so much about it. I just know that it performs well."&amp;nbsp; &lt;/EM&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt"&gt;Well you are correct but not really correct. I hope you want to go down to the metal. So please read on… :) &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt"&gt;WCF uses CLR thread pool threads to do things asynchronously. However, interestingly it uses IO worker threads in the thread pool instead of the regular thread pool worker threads (don't fuzz if you are not aware of these two kinds of threads). The theory behind IO worker threads reveals a lot about why WCF use it. Therefore I thought I would dedicate this post to talk a little bit about it. &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt"&gt;So before we actually dig in let me ask you a simple question. When do you consider that you are taking max out of your CPU? Is it when a single thread trying to take up 100% or multiple threads trying take up 100%? I know, you said single thread 100% case which is correct. When you have multiple CPU bound threads additional costs of things like context switching slow things down. Wanna see it yourself? Write a small lengthy loop. Measure the time it takes when you run it in a single thread. Then delegate it to several threads and again measure the time that each of them take to finish it and compare the values. &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt"&gt;So… technically speaking, we can achieve the best CPU utilization only by sticking to "One tread per CPU per execution quantum" invariant. &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt"&gt;I/O completion ports (IOCP) were introduce to Windows NT kernel to achieve this goal. Although it's a complex technology, the fundamental theory behind the scene is fairly straightforward. &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt"&gt;Before the invent of IOCP; there were two major IO programming techniques. One thread for all IO and one thread per IO. In one thread for all IO model; a thread that is IO bound had to wait doing nothing. Also all other IO operation were blocked until the one going on is done. Although this model was fair enough for single threaded client apps, server applications did not fit in at all. For example, if a simple server was written in this way it will serve only one client at a time. One thread per IO model on the other hand spawn up a new thread for each client. But this eventually ended up with too many threads striving for CPU. So we either have too few threads or too many threads causing the trouble.&lt;BR&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt"&gt;In order to solve this problem; IOCP work like a controller hub between two parties. In one end it receives IO completion packets saying that some work is available. On the other end it has some IO worker threads waiting for work. When an IOCP receives an I/O completion packet, it makes one of the waiting threads &lt;EM&gt;active&lt;/EM&gt; and delegate the available work (thread is picked up in LIFO order to avoid potential context switching). So what? How does this model help to solve problem we addressed earlier. The secret lies within NumberOfConcurrentThreads parameter value we pass when we create the IOCP using CreateIoCompletionPort function. This parameter tells IOCP how many &lt;EM&gt;concurrent&lt;/EM&gt; threads that we actually want to have &lt;EM&gt;active&lt;/EM&gt; to process the incoming work. The preferred value for this number equals to the number of CPUs you have in the box. So no matter how fast the work is being queued, we only have desired number of threads concurrently processing them. The other cool thing about this is; when an active IO worker thread goes to wait state (may be it's doing some more IO work), windows scheduler tells the pertaining IOCP that one of its active threads are inactive now. So that the IOCP can make another thread active to perform some other work (Smart! Isn't it? ;)). Consequently the number of active threads in an IOCP at given time is usually a little bit higher than the provided NumberOfConcurrentThreads value. &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt"&gt;OK. Now we know why IOCPs are so elegant. But how does WCF actually use it? Well... CLR thread pool has an IOCP associated with it. When thread pool creates its IOCP for the first time, it also creates IO worker threads which are waiting for work. So essentially, we can get an IO worker thread to do some work by sending an IO completion packet to this IOCP. To do that we can use ThreadPool.UnsafeQueueNativeOverlapped function (This method internally invokes the PostQueuedCompletionStatus function). Here is a little program to demonstrate how you could do that. &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas"&gt;&lt;FONT face="Courier New"&gt;static void Main(string[] args) &lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas"&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas"&gt;&lt;FONT face="Courier New"&gt;{ &lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas"&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;unsafe &lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas"&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp; { &lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas"&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Create an Overlapped structure and pack it with a pointer to the function &lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas"&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // that we want to invoke from the IO worker thread. &lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas"&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Overlapped overlapped = new Overlapped(0, 0, IntPtr.Zero, null); &lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas"&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; NativeOverlapped* pOverlapped = overlapped.UnsafePack(new IOCompletionCallback(OnIoCompletion), &lt;/FONT&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas"&gt;&lt;FONT face="Courier New"&gt;null); &lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas"&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp; &amp;nbsp; // Send an IO completion packet to thrad pool's IOCP &lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas"&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ThreadPool.UnsafeQueueNativeOverlapped(pOverlapped); &lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas"&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp; } &lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas"&gt;&lt;FONT face="Courier New"&gt;}&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas"&gt;&lt;FONT face="Courier New"&gt;static unsafe void OnIoCompletion(uint errorCode, uint numBytes, NativeOverlapped* pOverlapped) &lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas"&gt;&lt;FONT face="Courier New"&gt;{ &lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas"&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp; Console.WriteLine("This is from an IO worker thread"); &lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas"&gt;&lt;FONT face="Courier New"&gt;} &lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt"&gt;WCF also basically follows the same concept. But it has an elegantly designed queue based IO thread scheduler. I would like to dedicate a separate post to talk about how exactly it works. But if you are reflector fan like me, take a look at System.ServiveModel.IoThreadScheduler class and you will see it in your own eyes. &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt"&gt;So what does all this tell us? WCF uses this IoThreadScheduler to queue work items for IO worker threads. This way it preserves the "One thread per CPU per execution quantum" constant and achieves the best CPU utilization. It never (may be I should say I've never seen it but I have a lot of faith on the WCF team) uses ThreadPool.QueueUserWorkItem API and thus refrain from using regular thread pool worker threads (I'm sure now you see why WCF performs a lot better than ASMX runtime ;)). &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt"&gt;OK, are you still not certain that WCF is working this way? Cool! I guess you don't have too much faith on me. Well.. Then get ready for a little exercise. Create a little service with a single operation. Make this operation do some lengthy CPU intensive work (perhaps a loop doing some math). And then try to invoke this operation from multiple clients simultaneously (or you can call it from multiple threads in the same client). How many requests that your server can service concurrently? Looking forward to hearing your results :) &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt"&gt;Cheers &lt;/SPAN&gt;&lt;/P&gt;&lt;img src="http://blogs.thinktecture.com/aggbug.aspx?PostID=414902" width="1" height="1"&gt;</content><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.thinktecture.com/buddhike/commentrss.aspx?PostID=414902</wfw:commentRss></entry><entry><title>SOAP Routing – What has it gotta do with “To” header ??? </title><link rel="alternate" type="text/html" href="http://blogs.thinktecture.com/buddhike/archive/2007/05/25/414853.aspx" /><id>ff4ed322-7612-4f43-9d7f-220c081c7cfd:414853</id><created>2007-05-25T17:00:00Z</created><content type="text/html" mode="escaped">
&lt;p class="MsoNormal"&gt;During the past few days I came across some SOAP routing
intermediary implementations (of course running on WCF ;)) and each of them
were trying to route the WCF messages by changing the “To” WS-Addressing header
in the message. In some cases this even required completely reconstructing the
message by reading its body contents. This actually made me think about the
basics once again. What actually happens in the real routers? For example, does
Windows TDI driver for TCP/IP change the destination IP to your router’s IP
after looking at the routing table? No! Instead, the transport transmits the traffic
to the appropriate IP as specified in the routing table. Then the router reads
the destination IP in the incoming TCP segments and forwards the traffic to the
next network hop according to the routing table in the router itself. So essentially,
the router is a device that simply forwards messages without tweaking them. Likewise
this should be the theory behind the SOAP routers as well (of course SOAP works
at a much higher level and you can divert this approach to meet your custom
needs. But I’m talking about the routing in general).&lt;/p&gt;

&lt;p class="MsoNormal"&gt;So how exactly you can do this in WCF? The answer is hidden
in an attribute that you might not pay too much attention in your everyday WCF
adventures ;). When you configure an endpoint you can actually, specify the
service address as well as the actual listening address as follows.&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;b style=""&gt;[service endpoint]&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;"&gt;&lt;span style="font-size: 10pt; font-family: Consolas; color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Consolas; color: maroon;"&gt;endpoint&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Consolas; color: blue;"&gt; &lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Consolas; color: red;"&gt;address&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Consolas; color: blue;"&gt;=&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;"&lt;span style="color: blue;"&gt;http://localhost:8000/service/dummyendpoint.svc&lt;/span&gt;"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;"&gt;&lt;span style="font-size: 10pt; font-family: Consolas; color: red;"&gt;&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;listenUri&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Consolas; color: blue;"&gt;=&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;"&lt;span style="color: blue;"&gt;http://localhost:8000/service/actualendpoint.svc&lt;/span&gt;"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;"&gt;&lt;span style="font-size: 10pt; font-family: Consolas; color: red;"&gt;&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;contract&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Consolas; color: blue;"&gt;=&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;"&lt;span style="color: blue;"&gt;…&lt;/span&gt;"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;"&gt;&lt;span style="font-size: 10pt; font-family: Consolas; color: blue;"&gt;&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Consolas; color: red;"&gt;binding&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Consolas; color: blue;"&gt;=&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;"&lt;span style="color: blue;"&gt;…&lt;/span&gt;"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="font-size: 10pt; line-height: 115%; font-family: Consolas; color: blue;"&gt;&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; line-height: 115%; font-family: Consolas; color: red;"&gt;bindingConfiguration&lt;/span&gt;&lt;span style="font-size: 10pt; line-height: 115%; font-family: Consolas; color: blue;"&gt;=&lt;/span&gt;&lt;span style="font-size: 10pt; line-height: 115%; font-family: Consolas;"&gt;"&lt;span style="color: blue;"&gt;…&lt;/span&gt;"&lt;span style="color: blue;"&gt;
/&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;When you start your service the underlying transport
actually uses the address specified in the listenUri to listen to the incoming
traffic (if this is not specified, it uses the endpoint address by default).
The service address on the other hand is the one which goes in the
WS-Addressing “TO” header. This address is validated by service model layer to
make sure that the messages that arrive at the endpoint are truly intended for
this service (otherwise you’ll get the address filter mismatch error… remember
that? ;)). So with these two attributes in our hands we can successfully model
the aforementioned routing in the SOAP level as well. You can do it by having
your router service actually listening on the endpoint address specified in the
service (see below).&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;b style=""&gt;[router endpoint]&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;"&gt;&lt;span style="font-size: 10pt; font-family: Consolas; color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Consolas; color: maroon;"&gt;endpoint&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Consolas; color: blue;"&gt; &lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Consolas; color: red;"&gt;address&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Consolas; color: blue;"&gt;=&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;"&lt;span style="color: blue;"&gt;http://localhost:8000/service/dummyendpoint.svc&lt;/span&gt;"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;"&gt;&lt;span style="font-size: 10pt; font-family: Consolas; color: red;"&gt;&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;contract&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Consolas; color: blue;"&gt;=&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;"&lt;span style="color: blue;"&gt;…&lt;/span&gt;"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;"&gt;&lt;span style="font-size: 10pt; font-family: Consolas; color: blue;"&gt;&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Consolas; color: red;"&gt;binding&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Consolas; color: blue;"&gt;=&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;"&lt;span style="color: blue;"&gt;…&lt;/span&gt;"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="font-size: 10pt; line-height: 115%; font-family: Consolas; color: blue;"&gt;&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; line-height: 115%; font-family: Consolas; color: red;"&gt;bindingConfiguration&lt;/span&gt;&lt;span style="font-size: 10pt; line-height: 115%; font-family: Consolas; color: blue;"&gt;=&lt;/span&gt;&lt;span style="font-size: 10pt; line-height: 115%; font-family: Consolas;"&gt;"&lt;span style="color: blue;"&gt;…&lt;/span&gt;"&lt;span style="color: blue;"&gt;
/&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;Then you can simply forward the messages to the actual
service endpoints according your routing rules. For example, you can determine
a message to the above service endpoint by looking at the action header of the
incoming message and forward it to the service by making a channel to &lt;span style="font-size: 10pt; line-height: 115%; font-family: Consolas; color: blue;"&gt;&lt;a href="http://localhost:8000/service/actualendpoint.svc"&gt;http://localhost:8000/service/actualendpoint.svc&lt;/a&gt;
&lt;/span&gt;endpoint (which is the actual endpoint of our service). Also note that
this way, no matter how many intermediaries the message passes through the
WS-Addressing “TO” header remains consistent.&lt;/p&gt;

&lt;p class="MsoNormal"&gt;When I started writing this post I intended to provide a very
rough sample that I created couple of months ago (in fact I gave up re-inventing
the wheel after seeing &lt;a href="http://blogs.msdn.com/shycohen/"&gt;Shy Cohen’s&lt;/a&gt; wonderful &lt;a href="http://msdn.microsoft.com/msdntv/episode.aspx?xml=episodes/en/20050825IndigoSC/manifest.xml"&gt;lossy router&lt;/a&gt; ;)). But then I
realized that the &lt;a href="http://msdn2.microsoft.com/en-us/library/ms751497.aspx"&gt;SDK routing sample&lt;/a&gt; perfectly demonstrates this. So
take a look at it to get a better picture on it.&lt;/p&gt;

&lt;p class="MsoNormal"&gt;Have fun!&lt;/p&gt;&lt;img src="http://blogs.thinktecture.com/aggbug.aspx?PostID=414853" width="1" height="1"&gt;</content><slash:comments>1</slash:comments><wfw:commentRss>http://blogs.thinktecture.com/buddhike/commentrss.aspx?PostID=414853</wfw:commentRss></entry><entry><title>WCF - POX Streaming</title><link rel="alternate" type="text/html" href="http://blogs.thinktecture.com/buddhike/archive/2007/05/23/414851.aspx" /><id>ff4ed322-7612-4f43-9d7f-220c081c7cfd:414851</id><created>2007-05-23T13:08:25Z</created><content type="text/html" mode="escaped">&lt;p&gt;Have you ever thought about returning a plain old XML document or some well formed HTML body snippet (for some crazy reason ;)) or your RSS feed from a WCF service? Well… I did &lt;span style="font-family: Wingdings;"&gt;:)&lt;/span&gt;. In fact instead of returning the XML document itself, I wanted to stream it as the data source I was anticipating was not fast enough to provide me the complete document at once (i.e. it takes considerably more time to receive the portions of the document than the time taken for the actual transmission). 
&lt;/p&gt;&lt;p&gt;So my long (well… it's not really long) journey towards a solution started with the contract (oh! Nah! I'm not going to play that famous record once again ;)).
&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;[&lt;span style="color: purple;"&gt;OperationContract&lt;/span&gt;(Action = &lt;span style="color: maroon;"&gt;"*"&lt;/span&gt;, ReplyAction=&lt;span style="color: maroon;"&gt;"*"&lt;/span&gt;)]
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;&lt;span style="color: purple;"&gt;Message&lt;/span&gt; GetWeather();&lt;/span&gt;
	&lt;/p&gt;&lt;p&gt; My contract has only one operation. By default WCF uses SOAP action headers in the incoming/outgoing messages to properly dispatch them to the service/client. But in this case I have nothing SOAPish in my payload. Therefore, by setting Action="*" in my OperationContract I'm telling WCF that anything comes into the configured endpoint of this service must be dispatched to this method.
&lt;/p&gt;&lt;p&gt;Moving on  to my operation implementation, I have a single line of code that simply constructs a Message and return it to the runtime which takes care of transmitting it back to the client. 
&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt;
			&lt;span style="color: purple;"&gt;Message&lt;/span&gt; GetWeather()
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;{            
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp;
			&lt;span style="color: purple;"&gt;Message&lt;/span&gt; msg = &lt;span style="color: purple;"&gt;Message&lt;/span&gt;.CreateMessage(&lt;span style="color: purple;"&gt;MessageVersion&lt;/span&gt;.None, &lt;span style="color: maroon;"&gt;"*"&lt;/span&gt;, &lt;span style="color: blue;"&gt;new&lt;/span&gt;
			&lt;span style="color: purple;"&gt;WeatherReport&lt;/span&gt;());            
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp;
			&lt;span style="color: blue;"&gt;return&lt;/span&gt; msg;
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;}&lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;So much of my solution lies within this line nevertheless. Let me brief you, Message is the fundamental unit of data transfer in WCF (if you have some socket background, think of it as the byte arrays in the world of sockets). You can create a message by calling one of the CreateMessage overloads in Message class. In WCF, these overloads are provided to support both push and pull mode data transfers. So in my case, I'm going for a push mode transfer and I'm doing it using an XML BodyWriter. You can create a BodyWriter by inheriting the BodyWriter abstract class. Then override the OnWriteBodyContenets, which is invoked by WCF runtime when it wants to serialize the message body. The runtime provides us a pointer to the XmlDictionaryWriter which, we can use to push the body contents. Consequently in my case I implemented my body writer in the WeatherReport class and wrote the XML document I wanted to send to the client in its OnWriteBodyContents overload. 
&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;&lt;span style="color: blue;"&gt;protected&lt;/span&gt;
			&lt;span style="color: blue;"&gt;override&lt;/span&gt;
			&lt;span style="color: blue;"&gt;void&lt;/span&gt; OnWriteBodyContents(&lt;span style="color: purple;"&gt;XmlDictionaryWriter&lt;/span&gt; writer)
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;{
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp;    writer.WriteStartElement(&lt;span style="color: maroon;"&gt;"weatherReport"&lt;/span&gt;);
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp;
			&lt;span style="color: purple;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: maroon;"&gt;"Sending weather report for Colombo"&lt;/span&gt;);
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp; writer.WriteStartElement(&lt;span style="color: maroon;"&gt;"Colombo"&lt;/span&gt;);
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp; writer.WriteAttributeString(&lt;span style="color: maroon;"&gt;"temp"&lt;/span&gt;, &lt;span style="color: maroon;"&gt;"26"&lt;/span&gt;);
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp; writer.WriteAttributeString(&lt;span style="color: maroon;"&gt;"wind"&lt;/span&gt;, &lt;span style="color: maroon;"&gt;"SW"&lt;/span&gt;);
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp; writer.WriteAttributeString(&lt;span style="color: maroon;"&gt;"humidity"&lt;/span&gt;, &lt;span style="color: maroon;"&gt;"79"&lt;/span&gt;);
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp; writer.Flush();
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp;
			&lt;span style="color: purple;"&gt;Thread&lt;/span&gt;.Sleep(3000); &lt;span style="color: green;"&gt;//&lt;/span&gt;&lt;span style="color: lime;"&gt;
			&lt;/span&gt;&lt;span style="color: green;"&gt;Simulate an I/O delay in the data source&lt;/span&gt;&lt;span style="color: lime;"&gt;
			&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp;
			&lt;span style="color: purple;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: maroon;"&gt;"Sending weather report for Munich"&lt;/span&gt;);
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp; writer.WriteStartElement(&lt;span style="color: maroon;"&gt;"Munich"&lt;/span&gt;);
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp; writer.WriteAttributeString(&lt;span style="color: maroon;"&gt;"temp"&lt;/span&gt;, &lt;span style="color: maroon;"&gt;"25"&lt;/span&gt;);
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp; writer.WriteAttributeString(&lt;span style="color: maroon;"&gt;"wind"&lt;/span&gt;, &lt;span style="color: maroon;"&gt;"NE"&lt;/span&gt;);
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp; writer.WriteAttributeString(&lt;span style="color: maroon;"&gt;"humidity"&lt;/span&gt;, &lt;span style="color: maroon;"&gt;"37"&lt;/span&gt;);
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp; writer.Flush();
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp; &lt;span style="color: purple;"&gt;Thread&lt;/span&gt;.Sleep(3000);
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp; &lt;span style="color: purple;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: maroon;"&gt;"Sending weather report for Seattle"&lt;/span&gt;);
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp; writer.WriteStartElement(&lt;span style="color: maroon;"&gt;"Seattle"&lt;/span&gt;);
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp; writer.WriteAttributeString(&lt;span style="color: maroon;"&gt;"temp"&lt;/span&gt;, &lt;span style="color: maroon;"&gt;"15"&lt;/span&gt;);
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp; writer.WriteAttributeString(&lt;span style="color: maroon;"&gt;"wind"&lt;/span&gt;, &lt;span style="color: maroon;"&gt;"SW"&lt;/span&gt;);
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp; writer.WriteAttributeString(&lt;span style="color: maroon;"&gt;"humidity"&lt;/span&gt;, &lt;span style="color: maroon;"&gt;"80"&lt;/span&gt;);
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp; writer.WriteEndElement();            
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp; writer.Flush();
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;}
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;You might have already noticed that in the above code, I call writer.Flush() several times. I do this when I've written enough data that the client can understand (weather report for one city in this case) so that it will be transmitted to the client immediately. However, in order make sure that the data is sent back to the client immediately, we have to make sure that we are on the streaming mode. This has to be specified in our binding.  I'm setting up my A(address),B(binding) and C(contract) imperatively in the code as follows.
&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;&lt;span style="color: purple;"&gt;CustomBinding&lt;/span&gt; binding = &lt;span style="color: blue;"&gt;new&lt;/span&gt;
			&lt;span style="color: purple;"&gt;CustomBinding&lt;/span&gt;();
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: green; font-family: Consolas; font-size: 10pt;"&gt;// Encoder
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;&lt;span style="color: purple;"&gt;TextMessageEncodingBindingElement&lt;/span&gt; encoder = &lt;span style="color: blue;"&gt;new&lt;/span&gt;
			&lt;span style="color: purple;"&gt;TextMessageEncodingBindingElement&lt;/span&gt;();
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;encoder.MessageVersion = &lt;span style="color: purple;"&gt;MessageVersion&lt;/span&gt;.None;            
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;binding.Elements.Add(encoder);
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: green; font-family: Consolas; font-size: 10pt;"&gt;// Transport
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;&lt;span style="color: purple;"&gt;HttpTransportBindingElement&lt;/span&gt; transport = &lt;span style="color: blue;"&gt;new&lt;/span&gt;
			&lt;span style="color: purple;"&gt;HttpTransportBindingElement&lt;/span&gt;();
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;transport.TransferMode = &lt;span style="color: purple;"&gt;TransferMode&lt;/span&gt;.StreamedResponse;
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;transport.MaxBufferSize = 256;           
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;binding.Elements.Add(transport);
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: green; font-family: Consolas; font-size: 10pt;"&gt;// We will take about 10 minutes for our transmission.
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;binding.SendTimeout = &lt;span style="color: purple;"&gt;TimeSpan&lt;/span&gt;.FromMinutes(10);
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;&lt;span style="color: purple;"&gt;ServiceHost&lt;/span&gt; host = &lt;span style="color: blue;"&gt;new&lt;/span&gt;
			&lt;span style="color: purple;"&gt;ServiceHost&lt;/span&gt;(&lt;span style="color: blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color: purple;"&gt;MyService&lt;/span&gt;));
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;host.AddServiceEndpoint(&lt;span style="color: blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color: purple;"&gt;IMyService&lt;/span&gt;), binding,
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;
			&lt;span style="color: maroon;"&gt;"http://localhost:8011/myservice"&lt;/span&gt;);
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;host.Open();&lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;In this case, my binding contains only the most critical elements, the encoder and the transport we need to host a service. While setting up my encoder I set its MessageVersion property to MessageVersion.None. By doing this I'm telling the encoder that I want to get rid of all the SOAPish stuff in the message finally serialized (&lt;em&gt;Tip: this is your key if you want to do non SOAP transfers&lt;/em&gt;). And the in the transport I set the transfer mode to StreamedResponse to stream the responses from my service (when we enable streaming in the http transport, it streams the content as specified in the chunked transfer coding in the HTTP spec). Furthermore I set the MaxBufferSize to 256 bytes since we are only sending a very small chunk at a time. This way you can optimize the memory consumption for read/write buffers used for streaming (default is 64K). Finally I create the ServiceHost and call the Open method in that to start the service.
&lt;/p&gt;&lt;p&gt;On the client side, I setup my binding in almost the same way I did it in the service. Then I create a channel to communicate with my service endpoint and invoke the GetWeather operation. When I receive an instance of the Message class from the client side runtime, I get an XmlDictionaryReader at the body contents that I can use to read the underlying XML stream. 
&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;&lt;span style="color: purple;"&gt;Message&lt;/span&gt; playlist = myservice.GetWeather();
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;&lt;span style="color: purple;"&gt;XmlDictionaryReader&lt;/span&gt; reader = playlist.GetReaderAtBodyContents();
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;&lt;span style="color: blue;"&gt;while&lt;/span&gt; (reader.Read())
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;{
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp;
			&lt;span style="color: blue;"&gt;switch&lt;/span&gt; (reader.NodeType)
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp;    {
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
			&lt;span style="color: blue;"&gt;case&lt;/span&gt;
			&lt;span style="color: purple;"&gt;XmlNodeType&lt;/span&gt;.Element:                        
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
			&lt;span style="color: purple;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: maroon;"&gt;"{0} Temp:{1} Wind:{2} humidity:{3}"&lt;/span&gt;, 
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; reader.Name,
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; reader.GetAttribute(&lt;span style="color: maroon;"&gt;"temp"&lt;/span&gt;),
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; reader.GetAttribute(&lt;span style="color: maroon;"&gt;"wind"&lt;/span&gt;),
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; reader.GetAttribute(&lt;span style="color: maroon;"&gt;"humidity"&lt;/span&gt;));                        
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
			&lt;span style="color: blue;"&gt;break&lt;/span&gt;;
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
			&lt;span style="color: blue;"&gt;case&lt;/span&gt;
			&lt;span style="color: purple;"&gt;XmlNodeType&lt;/span&gt;.Text:                        
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
			&lt;span style="color: blue;"&gt;break&lt;/span&gt;;                        
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
			&lt;span style="color: blue;"&gt;case&lt;/span&gt;
			&lt;span style="color: purple;"&gt;XmlNodeType&lt;/span&gt;.EndElement:                        
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
			&lt;span style="color: blue;"&gt;break&lt;/span&gt;;&lt;br&gt;&amp;nbsp;&amp;nbsp; }                
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;}
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;reader.Close();&lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;Now, it is important to note that I've also set the MaxBytesPerRead quota to 64 bytes in ReaderQuotas property of my encoder. 
&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Consolas; font-size: 10pt;"&gt;encoder.ReaderQuotas.MaxBytesPerRead = 64;            &lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;This value indicates how many bytes the XmlDictionaryReader should read when reading the element start tag and its attributes. Therefore, this value should essentially be large enough to read that information. If you set an unnecessarily large value here, the XmlDictionaryReader.Read() method will not return until it receives enough bytes from the underlying transport (this could be problematic if you receive very small data chunks with a considerable amount of delay as demonstrated in my code). Consequently you would not be able to read the data being streamed in timely fashion (this might even make you think that your data not actually streamed ;)).
&lt;/p&gt;&lt;p&gt;You can download my sample code &lt;a href="http://blogs.thinktecture.com/buddhike/files/streamingxml.zip"&gt;here&lt;/a&gt; and take a good look at it. Questions, ideas and corrections are welcomed!
&lt;/p&gt;&lt;p&gt;Cheers,
&lt;/p&gt;&lt;img src="http://blogs.thinktecture.com/aggbug.aspx?PostID=414851" width="1" height="1"&gt;</content><slash:comments>4</slash:comments><wfw:commentRss>http://blogs.thinktecture.com/buddhike/commentrss.aspx?PostID=414851</wfw:commentRss></entry><entry><title>thinktecture</title><link rel="alternate" type="text/html" href="http://blogs.thinktecture.com/buddhike/archive/2007/05/21/414848.aspx" /><id>ff4ed322-7612-4f43-9d7f-220c081c7cfd:414848</id><created>2007-05-21T06:07:00Z</created><content type="text/html" mode="escaped">

&lt;p class="MsoNormal"&gt;Yesterday I was organizing my 7000+ photo gallery and
suddenly noted something which, none of us have posted yet. It’s been a while
since we did some cool modifications to&lt;a href="http://www.thinktecture.com/staff/"&gt; thinktecture family&lt;/a&gt; ;). Although Ingo and
Christian posted about the addition of our friends Neno and Dominick let me be the very
&lt;b style=""&gt;first&lt;/b&gt; to post a picture of us ;).&lt;/p&gt;

&lt;img src="http://farm1.static.flickr.com/200/507279325_a4ba40cbe3.jpg?v=0"&gt;&lt;img src="http://blogs.thinktecture.com/aggbug.aspx?PostID=414848" width="1" height="1"&gt;</content><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.thinktecture.com/buddhike/commentrss.aspx?PostID=414848</wfw:commentRss></entry><entry><title>Cleaning up Client Channels</title><link rel="alternate" type="text/html" href="http://blogs.thinktecture.com/buddhike/archive/2007/05/13/414844.aspx" /><id>ff4ed322-7612-4f43-9d7f-220c081c7cfd:414844</id><created>2007-05-13T21:02:00Z</created><content type="text/html" mode="escaped">

&lt;p class="MsoNormal"&gt;Most of us have our own style of writing code we’ve been
practicing throughout our career. Using the “using” statement for deterministic
resource cleanup is one of my must haves in my keywords bag. But unfortunately
I cannot use this to clean up the client channels I use in WCF. For example, if
I use the following piece of code I’m unwittingly opening up a place where my
program would simply crash. Why?&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;"&gt;&lt;span style="font-size: 10pt; font-family: Consolas; color: blue;"&gt;using&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt; (&lt;span style="color: purple;"&gt;IClientChannel&lt;/span&gt; client = (&lt;span style="color: purple;"&gt;IClientChannel&lt;/span&gt;)cf.CreateChannel())&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: purple;"&gt;IFoo&lt;/span&gt;
foo = (&lt;span style="color: purple;"&gt;IFoo&lt;/span&gt;)client;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;foo.Bar();&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="font-size: 10pt; line-height: 115%; font-family: Consolas;"&gt;}&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;The above code merely means that the following line will be
executed upon exiting the using block.&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="font-size: 10pt; line-height: 115%; font-family: Consolas;"&gt;((&lt;span style="color: purple;"&gt;IDisposable&lt;/span&gt;)client).Dispose()&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;And the answer to above “Why?” actually lies within the
Dispose implementation in the IClientChannel implementation. If we reflector System.ServiceModel.Channels.ServiceChannel,
one of the IClientChannel implementers in WCF, we can clearly see that its
Dispose implementation calls Close method in its base class
CommunicationObject. In the world of CommunicationObjects, Close does not
necessarily mean that everything will be fine. Likewise, when we call Close, we
are essentially telling WCF to gracefully close the client channel. However,
the evil things could still happen. For example, soon after calling Close we
might lose the network connectivity before the channel can successfully send
the protocol level messages that are required to terminate the current session.
&lt;/p&gt;

&lt;p class="MsoNormal"&gt;So the bottom line is Close() can throw. And we have to be
aware of it and write our code in a way that it does not crash even if the
Close throws. There can be two kinds of things that can happened if something
goes wrong while communicating with the service. Namely they are timeout
exceptions and communication exceptions (yes, communication exceptions can be
further broken into exceptions that inherits the CommunicationException, such
as FaultException). When these things happen we should call Abort() in our client
channel object to bring it to Closed state and throw away. Consequently the
above code can be written better using the try/catch/abort pattern as follows.&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;"&gt;&lt;span style="font-size: 10pt; font-family: Consolas; color: purple;"&gt;IFoo&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt; client = &lt;span style="color: blue;"&gt;null&lt;/span&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;"&gt;&lt;span style="font-size: 10pt; font-family: Consolas; color: blue;"&gt;try&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;client = cf.CreateChannel();&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;client.Bar();&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;((&lt;span style="color: purple;"&gt;IClientChannel&lt;/span&gt;)client).Close();&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;"&gt;&lt;span style="font-size: 10pt; font-family: Consolas; color: blue;"&gt;catch&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt; (&lt;span style="color: purple;"&gt;TimeoutException&lt;/span&gt;)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;((&lt;span style="color: purple;"&gt;IClientChannel&lt;/span&gt;)client).Abort();&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;"&gt;&lt;span style="font-size: 10pt; font-family: Consolas; color: blue;"&gt;catch&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt; (&lt;span style="color: purple;"&gt;CommunicationException&lt;/span&gt;)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;((&lt;span style="color: purple;"&gt;IClientChannel&lt;/span&gt;)client).Abort();&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="font-size: 10pt; line-height: 115%; font-family: Consolas;"&gt;}&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;This code is fine as far as we call client channel methods within
the try block. As soon as we have something else going on, we cannot guarantee
that the code will only throw exceptions of these two types. &lt;span style=""&gt;&amp;nbsp;&lt;/span&gt;For example consider a modified version of
above code snippet like this.&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;"&gt;&lt;span style="font-size: 10pt; font-family: Consolas; color: purple;"&gt;IFoo&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt; client = &lt;span style="color: blue;"&gt;null&lt;/span&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;



&lt;p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;"&gt;&lt;span style="font-size: 10pt; font-family: Consolas; color: blue;"&gt;&lt;o:p&gt;&lt;/o:p&gt;try&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;client = cf.CreateChannel();&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;client.Bar();&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: blue;"&gt;int&lt;/span&gt;
x = 0, y = 0, z = 0;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: green;"&gt;// do
some math to yeild x and y&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;z = x / y;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;"&gt;&lt;span style="font-size: 10pt; font-family: Consolas;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;((&lt