<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" version="2.0">
  <channel>
    <title>.NET Meanderings</title>
    <link>http://www.dotnetconsult.co.uk/weblog2/</link>
    <description>Richard Blewett's wanderings around .NET</description>
    <language>en-us</language>
    <copyright>Richard Blewett</copyright>
    <lastBuildDate>Thu, 02 Jul 2009 12:02:39 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 1.9.6264.0</generator>
    <managingEditor>richard@dotnetconsult.co.uk</managingEditor>
    <webMaster>richard@dotnetconsult.co.uk</webMaster>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=9601b6a2-e1f5-4edd-bb8b-cdda9e6a481f</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,9601b6a2-e1f5-4edd-bb8b-cdda9e6a481f.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <wfw:comment>http://www.dotnetconsult.co.uk/weblog2/CommentView,guid,9601b6a2-e1f5-4edd-bb8b-cdda9e6a481f.aspx</wfw:comment>
      <wfw:commentRss>http://www.dotnetconsult.co.uk/weblog2/SyndicationService.asmx/GetEntryCommentsRss?guid=9601b6a2-e1f5-4edd-bb8b-cdda9e6a481f</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
In my <a href="http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,0464ef2a-cbaf-4cd1-8f05-d058a0503a2f.aspx">last
post</a> I linked to the screencast I made on processing large messages in WCF using
buffering. I also said that I would be putting up another one on streaming messages
shortly. That second screencast has now gone live on the <a href="http://rocksolidknowledge.com/">Rock
Solid Knowledge website</a>. In part 2 of the large message handling screencast I
talk about enabling streaming, designing contracts for streaming and how this affects
the way the receiver has to process the data. You can find the new screencast here
</p>
        <p>
          <a href="http://rocksolidknowledge.com/ScreenCasts.mvc">http://rocksolidknowledge.com/ScreenCasts.mvc</a>
        </p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=9601b6a2-e1f5-4edd-bb8b-cdda9e6a481f" />
      </body>
      <title>New Screencast: Streamed Messages in WCF</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,9601b6a2-e1f5-4edd-bb8b-cdda9e6a481f.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,9601b6a2-e1f5-4edd-bb8b-cdda9e6a481f.aspx</link>
      <pubDate>Thu, 02 Jul 2009 12:02:39 GMT</pubDate>
      <description>&lt;p&gt;
In my &lt;a href="http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,0464ef2a-cbaf-4cd1-8f05-d058a0503a2f.aspx"&gt;last
post&lt;/a&gt; I linked to the screencast I made on processing large messages in WCF using
buffering. I also said that I would be putting up another one on streaming messages
shortly. That second screencast has now gone live on the &lt;a href="http://rocksolidknowledge.com/"&gt;Rock
Solid Knowledge website&lt;/a&gt;. In part 2 of the large message handling screencast I
talk about enabling streaming, designing contracts for streaming and how this affects
the way the receiver has to process the data. You can find the new screencast here
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://rocksolidknowledge.com/ScreenCasts.mvc"&gt;http://rocksolidknowledge.com/ScreenCasts.mvc&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=9601b6a2-e1f5-4edd-bb8b-cdda9e6a481f" /&gt;</description>
      <comments>http://www.dotnetconsult.co.uk/weblog2/CommentView,guid,9601b6a2-e1f5-4edd-bb8b-cdda9e6a481f.aspx</comments>
      <category>.NET;WCF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=0464ef2a-cbaf-4cd1-8f05-d058a0503a2f</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,0464ef2a-cbaf-4cd1-8f05-d058a0503a2f.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <wfw:comment>http://www.dotnetconsult.co.uk/weblog2/CommentView,guid,0464ef2a-cbaf-4cd1-8f05-d058a0503a2f.aspx</wfw:comment>
      <wfw:commentRss>http://www.dotnetconsult.co.uk/weblog2/SyndicationService.asmx/GetEntryCommentsRss?guid=0464ef2a-cbaf-4cd1-8f05-d058a0503a2f</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I’ve just uploaded a new screencast on to <a href="http://rocksolidknowledge.com">Rock
Solid Knowledge</a>. This one walks though configuring WCF to be able to pass large
messages between client and service. Its the of two parts, this one talks about the
default mode WCF uses for transferring data – buffering. I’ll be doing another one
soon that looks at WCF in streaming mode.
</p>
        <p>
You can find the screencast <a href="http://rocksolidknowledge.com/ScreenCasts.mvc">here</a></p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=0464ef2a-cbaf-4cd1-8f05-d058a0503a2f" />
      </body>
      <title>New Screencast: Working with Large Messages in WCF (Part 1)</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,0464ef2a-cbaf-4cd1-8f05-d058a0503a2f.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,0464ef2a-cbaf-4cd1-8f05-d058a0503a2f.aspx</link>
      <pubDate>Thu, 18 Jun 2009 12:04:34 GMT</pubDate>
      <description>&lt;p&gt;
I’ve just uploaded a new screencast on to &lt;a href="http://rocksolidknowledge.com"&gt;Rock
Solid Knowledge&lt;/a&gt;. This one walks though configuring WCF to be able to pass large
messages between client and service. Its the of two parts, this one talks about the
default mode WCF uses for transferring data – buffering. I’ll be doing another one
soon that looks at WCF in streaming mode.
&lt;/p&gt;
&lt;p&gt;
You can find the screencast &lt;a href="http://rocksolidknowledge.com/ScreenCasts.mvc"&gt;here&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=0464ef2a-cbaf-4cd1-8f05-d058a0503a2f" /&gt;</description>
      <comments>http://www.dotnetconsult.co.uk/weblog2/CommentView,guid,0464ef2a-cbaf-4cd1-8f05-d058a0503a2f.aspx</comments>
      <category>.NET;WCF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=b891610a-6b78-4b54-b9a6-4ec81c82b7c0</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,b891610a-6b78-4b54-b9a6-4ec81c82b7c0.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <wfw:comment>http://www.dotnetconsult.co.uk/weblog2/CommentView,guid,b891610a-6b78-4b54-b9a6-4ec81c82b7c0.aspx</wfw:comment>
      <wfw:commentRss>http://www.dotnetconsult.co.uk/weblog2/SyndicationService.asmx/GetEntryCommentsRss?guid=b891610a-6b78-4b54-b9a6-4ec81c82b7c0</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I am one of the moderators of the <a href="http://social.msdn.microsoft.com/Forums/en-US/wcf/threads">MSDN
WCF Forum</a>. One of the main areas of questions on the forum is duplex messaging
– particularly using the WSDualHttpBinding. So instead of typing long messages repeating
the same thing in answer to these questions I’ve decided to write this blog post to
give a bit of background about duplex messaging and then discuss the options for bindings
and common problems people have.
</p>
        <h5>What is Duplex Messaging?
</h5>
        <p>
There are many ways that messages can be exchanged between two parties in a service
based system: the client can send messages to the server and never get any back; the
client can send a message and wait for a response; the client and service can send
eachother messages without any pre-defined pattern; the client can send the service
a message but not wait synchronously for a response and then then service can send
a message back asynchronously; and there are many others. However, the first three
of these are supported natively in WCF and are known as One-way, request/response
and duplex. 
</p>
        <p>
So Duplex messaging is where, unsolicited, the client and service can send eachother
messages. Most commonly this is characterized by the service sending the client “events”
or notifications or progress of “interesting things”.
</p>
        <h5>Duplex Contracts in WCF
</h5>
        <p>
To send messages to eachother the client and service must have an idea of what operations
are available and what messages are sent and received during the communication. In
WCF this idea is modelled by the contract. Now normally a contract just determines
what functionality is available at the service. However, now the service is going
to be sending messages to the client that the client isn’t specifically waiting for
so it needs an idea of what messages the client can deal with. So we need a contract
that models both directions of the conversation.
</p>
        <p>
A bi-directional contract is modelled using two interfaces bound together with a ServiceContract
– like this:
</p>
        <p>
        </p>
        <div id="codeSnippetWrapper">
          <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">[ServiceContract(<strong>CallbackContract=<span style="color: #0000ff">typeof</span>(IPizzaProgress)</strong>)]</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #0000ff">interface</span> IOrderPizza</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">{</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">    [OperationContract]</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #0000ff">void</span> PlaceOrder(<span style="color: #0000ff">string</span> PizzaType);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">}</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #0000ff">interface</span> IPizzaProgress</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">{</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">    [OperationContract]</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #0000ff">void</span> TimeRemaining(<span style="color: #0000ff">int</span> minutes);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">    [OperationContract]</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #0000ff">void</span> PizzaReady();</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">}</pre>
            <!--CRLF-->
          </div>
        </div>
        <p>
The import bit here is the CallbackContract that establishes the relationship between
the service’s and client’s contracts.
</p>
        <h5>Writing the Service
</h5>
        <p>
The service is implemented normally apart from two issues: firstly it needs to access
the callback contract to be able to send messages back to the client; secondly the
communication infrastructure (modelled by the binding) needs to be able to cope with
duplex messaging. Firstly lets look at accessing the callback contract:
</p>
        <div id="codeSnippetWrapper">
          <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #0000ff">class</span> PingService
: IOrderPizza</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">{</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">    IPizzaProgress callback;</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #0000ff">public</span>
              <span style="color: #0000ff">void</span> PlaceOrder(<span style="color: #0000ff">string</span> PizzaType)</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">    {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <strong>callback
= OperationContext.Current.GetCallbackChannel<IPizzaProgress>
();
</IPizzaProgress></strong>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">        Action preparePizza = PreparePizza;</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">        preparePizza.BeginInvoke(ar =&gt; preparePizza.EndInvoke(ar), <span style="color: #0000ff">null</span>);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">    }</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #0000ff">void</span> PreparePizza()</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">    {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #0000ff">for</span> (<span style="color: #0000ff">int</span> i
= 10 - 1; i &gt;= 0; i--)</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">        {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">            callback.TimeRemaining(i);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">            Thread.Sleep(1000);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">        }</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">        callback.PizzaReady();</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">    }</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">}</pre>
            <!--CRLF-->
          </div>
        </div>
        <p>
        </p>
        <p>
The critical line here is calling GetCallbackContract on the OperationContext. This
gives the service access to a proxy to call back to the client.
</p>
        <p>
Now the service also needs to use a contract that is compatible with duplex messaging.
WSHttpBinding is the default for the built in WCF projects but it does not support
duplex messaging. People generally then move to the WSDualHttpBinding which is similar
to the WSHttpBinding but does support duplex. I will go into more depth about bindings
for duplex shortly but for now lets stick to this for now - it will work in our test
rig on a single machine without issue.
</p>
        <h5>Writing the Client
</h5>
        <p>
If the client is going to receive these messages it needs to provide an implementation
of the callback contract. It can gets its definition from either a shared contract
assembly or from metadata. If using metadata the callback contract will be named the
same as the service’s contract but with the work Callback appended. It will also need
to supply this implementation to the WCF infrastructure and it does this by wrapping
an instance in an InstanceContext object and passing it to the proxy constructor.
So here is the client:
</p>
        <div id="codeSnippetWrapper">
          <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #0000ff">class</span> Program</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">{</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #0000ff">static</span>
              <span style="color: #0000ff">void</span> Main(<span style="color: #0000ff">string</span>[]
args)</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">    {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <strong> InstanceContext
ctx = <span style="color: #0000ff">new</span> InstanceContext(<span style="color: #0000ff">new</span> Callback());</strong>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">        OrderPizzaClient proxy = <span style="color: #0000ff">new</span> OrderPizzaClient(ctx);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">        proxy.PlaceOrder(<span style="color: #006080">"Pepperoni"</span>);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">        Console.WriteLine(<span style="color: #006080">"press
enter to exit"</span>);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">        Console.ReadLine();</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">    }</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">}</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <strong>
                <span style="color: #0000ff">class</span> Callback
: IOrderPizzaCallback</strong>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">{</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #0000ff">public</span>
              <span style="color: #0000ff">void</span> TimeRemaining(<span style="color: #0000ff">int</span> minutes)</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">    {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">        Console.WriteLine(<span style="color: #006080">"{0}
seconds remaining"</span>, minutes);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">    }</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #0000ff">public</span>
              <span style="color: #0000ff">void</span> PizzaReady()</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">    {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">        Console.WriteLine(<span style="color: #006080">"Pizza
is ready"</span>);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">    }</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">}</pre>
            <!--CRLF-->
          </div>
        </div>
        <p>
Running the service and the client will have this working quite happily – so it would
seem that duplex messaging and WCF works very well … so why on earth do people keep
asking questions about it on the WCF forums?
</p>
        <h5>It Worked on My Machine but Broke when we Deployed It!
</h5>
        <p>
Ahh well you probably did the thing that is obvious but almost always a bad idea.
You went and chose WSDualHttpBinding as your duplex binding. To understand why this
is a bad idea we need to dig a little deeper into how the WSDualHttpBinding works.
HTTP is a unidirectional protocol: the client makes a request and the server sends
a response. There is no way for a server to initiate an exchange with the client.
So how on earth is duplex messaging going to work because it requires exactly this
facility? Well the “Dual” in the name is significant, the WSDualHttpBinding actually
consists of two connections: one outbound from client to server and one inbound from
server to client – this second connection may already be ringing alarm bells with
you. The are a two big problems with inbound connections to a client: firewalls very
often block inbound connections to clients; the client may not be reachable from the
server, it may be using NAT translation behind a router and so cannot be contacted
without port forwarding being set up on the router. Both of these issues are showstoppers
in real network topologies. You can take some small steps to help – you can specify
what port the client should listen on for example by using the clientBaseAddress property
of the WSDualHttpBinding. This means the network admin will only have to punch one
hole in their firewall (but lets face it, network admins don’t allow any holes to
be punched in the firewall).
</p>
        <p>
So if you really shouldn’t use WSDualHttpBinding for duplex, what should you use instead?
Well NetTcpBinding supports duplex out of the box and the nice thing about this is
that the outbound connection that it establishes can also be used be used for inbound
traffic – suddenly we don;t have the inbound connection firewall/NAT issues. “But
hold on, isn’t NetTcpBinding for intranet? I’ve read books that tell me that in their
‘which binding should I use?’ flowcharts!” Well it turns out those flowcharts are
talking rubbish – NetTcpBinding works very happily over the internet, its just not
interoperable by design. “Aha! but I need interop so WSDualHttpBinding is for me!”
Well unfortunately not, NetTcpBinding is non-interoperable by design, WSDualHttpBinding
is non-interoperable despite its design. From the name it would suggest interoperability
but Arun Gupta from Sun wrote <a href="http://blogs.sun.com/arungupta/entry/wshttpdualbinding_a_non_interoperable_binding">this
excellent post</a> describing why it wasn’t. 
</p>
        <p>
So now seeing that we really are not talking about interop anyway, NetTcpBinding is
far more useful than WSDualHttpBinding. Its not bullet proof, if the firewall only
allows outbound port 80 but also allows inbound port 80, then WSDualHttpBinding would
work where NetTcpBinding wouldn’t – but in this situation we’re really talking server
to server and so I’d argue its probably better to roll your own bidirectional communication
with two standard HTTP based connections.
</p>
        <p>
The final option you have for duplex communication is to add a piece of infrastructure
into the mix. <a href="http://www.microsoft.com/azure/servicebus.mspx">The .NET Services
Service Bus</a> (part of the Azure platform) allows two parties to exchange messages
both making outbound connections – potentially even using HTTP port 80. The two outbound
connections rendezvous in the Service Bus which mediates their message exchanges.
If the receiver has had to use outbound port 80 then it polls to receive message bound
for it.
</p>
        <h5>It Worked for the First 10 Clients and then the Rest Timed Out!
</h5>
        <p>
Irrespective if which of the standard bindings you are using, duplex assumes a constant
relationship between proxy and service. In WCF this idea is modelled by the concept
of session. All duplex bindings require session. A while back <a href="http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,af6e6325-2e30-42e3-acb9-57e1363fa51e.aspx">I
wrote in some detail about sessions</a>. You will have to either put up with increasing
the session throttle (see the linked article for details) or roll your own custom
binding that can do duplex without session – you can find an example of this <a href="http://blogs.msdn.com/ralph.squillace/archive/2006/10/10/Sessionless-duplex-services_3F00_-No-problem.-Small-issues_2C00_-yes_3B00_-problems_2C00_-no_2E00_.aspx">here</a>.
</p>
        <h5>I Use the Callback While the Client is calling the Service and it Deadlocks!
</h5>
        <p>
This is because your client is probably a Rich Client GUI based application (Windows
Forms or WPF). To understand why this is a problem we need to step back briefly and
look at UI clients, threading and WCF threading. UI applications have a rule: you
must only update the UI from the thread that created those UI components. In general
a GUI application has one UI thread so anything that changes the UI needs to be done
from that thread. .NET 2.0 introduced a new construct to simplify the process of a
background thread updating the UI: SynchronizationContext. The idea is that a UI framework
creates an implementation of a SynchronizationContext derived class that handles the
mechanics of marshalling a call on to the UI thread. An instance of this implementation
is then made available on the UI and accessible via the SynchronizationContext.Current. 
</p>
        <p>
WCF adds more complexity into the mix by enforcing a rule that says “unless you tell
me otherwise I will only allow one thread at a time into an object that I control”.
You see this with singleton services that will only allow one call at a time by default.
The same is also true of the callback implementation object – so WCF will only allow
one active thread in the client at a time. So while WCF is performing an outbound
call it will not allow an inbound call into the object. This causes the initial problem
with the deadlock that the service’s callback cannot be dispatched while the client’s
outbound call is in progress. To solve this we use the “unless you tell me otherwise”
part of the above rule. You do this by annotating the callback implementation class
with a [CallbackBehavior] attribute like this:
</p>
        <div id="codeSnippetWrapper">
          <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <strong>[CallbackBehavior(ConcurrencyMode=ConcurrencyMode.Reentrant)]</strong>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #0000ff">class</span> Callback
: IOrderPizzaCallback</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">{</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #0000ff">public</span>
              <span style="color: #0000ff">void</span> TimeRemaining(<span style="color: #0000ff">int</span> minutes)</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">    {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">        Console.WriteLine(<span style="color: #006080">"{0}
seconds remaining"</span>, minutes);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">    }</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #0000ff">public</span>
              <span style="color: #0000ff">void</span> PizzaReady()</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">    {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">        Console.WriteLine(<span style="color: #006080">"Pizza
is ready"</span>);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">    }</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">}</pre>
            <!--CRLF-->
          </div>
        </div>
        <p>
But now there is another problem: by default WCF will attempt to dispatch using an
available SynchronizationContext. The problem with this callback is the UI thread
is already blocked in an outbound call. SO for the call to dispatch we need to tell
WCF not to use the SynchronizationContext – again using the CallbackBehavior attribute:
</p>
        <div id="codeSnippetWrapper">
          <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">[CallbackBehavior(ConcurrencyMode=ConcurrencyMode.Reentrant, <strong>UseSynchronizationContext=<span style="color: #0000ff">false</span></strong>)]</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #0000ff">class</span> Callback
: IOrderPizzaCallback</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">{</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">    ...</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">}</pre>
            <!--CRLF-->
          </div>
        </div>
        <p>
Now the issue is of course that the call is going to be processed on a non UI thread
so you would have to manually marshal any UI interaction using the SynchronizationContext.Post
method.
</p>
        <p>
Duplex messaging can be a useful message exchange pattern but in WCF there can be
some unexpected issues. Hopefully this blog post clarifies those issues and demonstrates
workarounds for them.
</p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=b891610a-6b78-4b54-b9a6-4ec81c82b7c0" />
      </body>
      <title>WCF Duplex Messaging</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,b891610a-6b78-4b54-b9a6-4ec81c82b7c0.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,b891610a-6b78-4b54-b9a6-4ec81c82b7c0.aspx</link>
      <pubDate>Wed, 10 Jun 2009 06:54:13 GMT</pubDate>
      <description>&lt;p&gt;
I am one of the moderators of the &lt;a href="http://social.msdn.microsoft.com/Forums/en-US/wcf/threads"&gt;MSDN
WCF Forum&lt;/a&gt;. One of the main areas of questions on the forum is duplex messaging
– particularly using the WSDualHttpBinding. So instead of typing long messages repeating
the same thing in answer to these questions I’ve decided to write this blog post to
give a bit of background about duplex messaging and then discuss the options for bindings
and common problems people have.
&lt;/p&gt;
&lt;h5&gt;What is Duplex Messaging?
&lt;/h5&gt;
&lt;p&gt;
There are many ways that messages can be exchanged between two parties in a service
based system: the client can send messages to the server and never get any back; the
client can send a message and wait for a response; the client and service can send
eachother messages without any pre-defined pattern; the client can send the service
a message but not wait synchronously for a response and then then service can send
a message back asynchronously; and there are many others. However, the first three
of these are supported natively in WCF and are known as One-way, request/response
and duplex. 
&lt;/p&gt;
&lt;p&gt;
So Duplex messaging is where, unsolicited, the client and service can send eachother
messages. Most commonly this is characterized by the service sending the client “events”
or notifications or progress of “interesting things”.
&lt;/p&gt;
&lt;h5&gt;Duplex Contracts in WCF
&lt;/h5&gt;
&lt;p&gt;
To send messages to eachother the client and service must have an idea of what operations
are available and what messages are sent and received during the communication. In
WCF this idea is modelled by the contract. Now normally a contract just determines
what functionality is available at the service. However, now the service is going
to be sending messages to the client that the client isn’t specifically waiting for
so it needs an idea of what messages the client can deal with. So we need a contract
that models both directions of the conversation.
&lt;/p&gt;
&lt;p&gt;
A bi-directional contract is modelled using two interfaces bound together with a ServiceContract
– like this:
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;[ServiceContract(&lt;strong&gt;CallbackContract=&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(IPizzaProgress)&lt;/strong&gt;)]&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;interface&lt;/span&gt; IOrderPizza&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;{&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    [OperationContract]&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; PlaceOrder(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; PizzaType);&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;}&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;interface&lt;/span&gt; IPizzaProgress&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;{&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    [OperationContract]&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; TimeRemaining(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; minutes);&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    [OperationContract]&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; PizzaReady();&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;}&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
The import bit here is the CallbackContract that establishes the relationship between
the service’s and client’s contracts.
&lt;/p&gt;
&lt;h5&gt;Writing the Service
&lt;/h5&gt;
&lt;p&gt;
The service is implemented normally apart from two issues: firstly it needs to access
the callback contract to be able to send messages back to the client; secondly the
communication infrastructure (modelled by the binding) needs to be able to cope with
duplex messaging. Firstly lets look at accessing the callback contract:
&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;class&lt;/span&gt; PingService
: IOrderPizza&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;{&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    IPizzaProgress callback;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; PlaceOrder(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; PizzaType)&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    {&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        &lt;strong&gt;callback
= OperationContext.Current.GetCallbackChannel&lt;IPizzaProgress&gt;
();
&lt;/strong&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        Action preparePizza = PreparePizza;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        preparePizza.BeginInvoke(ar =&gt; preparePizza.EndInvoke(ar), &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;);&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    }&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; PreparePizza()&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    {&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #0000ff"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; i
= 10 - 1; i &gt;= 0; i--)&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        {&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;            callback.TimeRemaining(i);&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;            Thread.Sleep(1000);&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        }&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        callback.PizzaReady();&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    }&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;}&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
The critical line here is calling GetCallbackContract on the OperationContext. This
gives the service access to a proxy to call back to the client.
&lt;/p&gt;
&lt;p&gt;
Now the service also needs to use a contract that is compatible with duplex messaging.
WSHttpBinding is the default for the built in WCF projects but it does not support
duplex messaging. People generally then move to the WSDualHttpBinding which is similar
to the WSHttpBinding but does support duplex. I will go into more depth about bindings
for duplex shortly but for now lets stick to this for now - it will work in our test
rig on a single machine without issue.
&lt;/p&gt;
&lt;h5&gt;Writing the Client
&lt;/h5&gt;
&lt;p&gt;
If the client is going to receive these messages it needs to provide an implementation
of the callback contract. It can gets its definition from either a shared contract
assembly or from metadata. If using metadata the callback contract will be named the
same as the service’s contract but with the work Callback appended. It will also need
to supply this implementation to the WCF infrastructure and it does this by wrapping
an instance in an InstanceContext object and passing it to the proxy constructor.
So here is the client:
&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Program&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;{&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;[]
args)&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    {&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;strong&gt; InstanceContext
ctx = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; InstanceContext(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Callback());&lt;/strong&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        OrderPizzaClient proxy = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; OrderPizzaClient(ctx);&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        proxy.PlaceOrder(&lt;span style="color: #006080"&gt;"Pepperoni"&lt;/span&gt;);&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        Console.WriteLine(&lt;span style="color: #006080"&gt;"press
enter to exit"&lt;/span&gt;);&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        Console.ReadLine();&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    }&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;}&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;strong&gt;&lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Callback
: IOrderPizzaCallback&lt;/strong&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;{&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; TimeRemaining(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; minutes)&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    {&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        Console.WriteLine(&lt;span style="color: #006080"&gt;"{0}
seconds remaining"&lt;/span&gt;, minutes);&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    }&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; PizzaReady()&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    {&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        Console.WriteLine(&lt;span style="color: #006080"&gt;"Pizza
is ready"&lt;/span&gt;);&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    }&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;}&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
Running the service and the client will have this working quite happily – so it would
seem that duplex messaging and WCF works very well … so why on earth do people keep
asking questions about it on the WCF forums?
&lt;/p&gt;
&lt;h5&gt;It Worked on My Machine but Broke when we Deployed It!
&lt;/h5&gt;
&lt;p&gt;
Ahh well you probably did the thing that is obvious but almost always a bad idea.
You went and chose WSDualHttpBinding as your duplex binding. To understand why this
is a bad idea we need to dig a little deeper into how the WSDualHttpBinding works.
HTTP is a unidirectional protocol: the client makes a request and the server sends
a response. There is no way for a server to initiate an exchange with the client.
So how on earth is duplex messaging going to work because it requires exactly this
facility? Well the “Dual” in the name is significant, the WSDualHttpBinding actually
consists of two connections: one outbound from client to server and one inbound from
server to client – this second connection may already be ringing alarm bells with
you. The are a two big problems with inbound connections to a client: firewalls very
often block inbound connections to clients; the client may not be reachable from the
server, it may be using NAT translation behind a router and so cannot be contacted
without port forwarding being set up on the router. Both of these issues are showstoppers
in real network topologies. You can take some small steps to help – you can specify
what port the client should listen on for example by using the clientBaseAddress property
of the WSDualHttpBinding. This means the network admin will only have to punch one
hole in their firewall (but lets face it, network admins don’t allow any holes to
be punched in the firewall).
&lt;/p&gt;
&lt;p&gt;
So if you really shouldn’t use WSDualHttpBinding for duplex, what should you use instead?
Well NetTcpBinding supports duplex out of the box and the nice thing about this is
that the outbound connection that it establishes can also be used be used for inbound
traffic – suddenly we don;t have the inbound connection firewall/NAT issues. “But
hold on, isn’t NetTcpBinding for intranet? I’ve read books that tell me that in their
‘which binding should I use?’ flowcharts!” Well it turns out those flowcharts are
talking rubbish – NetTcpBinding works very happily over the internet, its just not
interoperable by design. “Aha! but I need interop so WSDualHttpBinding is for me!”
Well unfortunately not, NetTcpBinding is non-interoperable by design, WSDualHttpBinding
is non-interoperable despite its design. From the name it would suggest interoperability
but Arun Gupta from Sun wrote &lt;a href="http://blogs.sun.com/arungupta/entry/wshttpdualbinding_a_non_interoperable_binding"&gt;this
excellent post&lt;/a&gt; describing why it wasn’t. 
&lt;/p&gt;
&lt;p&gt;
So now seeing that we really are not talking about interop anyway, NetTcpBinding is
far more useful than WSDualHttpBinding. Its not bullet proof, if the firewall only
allows outbound port 80 but also allows inbound port 80, then WSDualHttpBinding would
work where NetTcpBinding wouldn’t – but in this situation we’re really talking server
to server and so I’d argue its probably better to roll your own bidirectional communication
with two standard HTTP based connections.
&lt;/p&gt;
&lt;p&gt;
The final option you have for duplex communication is to add a piece of infrastructure
into the mix. &lt;a href="http://www.microsoft.com/azure/servicebus.mspx"&gt;The .NET Services
Service Bus&lt;/a&gt; (part of the Azure platform) allows two parties to exchange messages
both making outbound connections – potentially even using HTTP port 80. The two outbound
connections rendezvous in the Service Bus which mediates their message exchanges.
If the receiver has had to use outbound port 80 then it polls to receive message bound
for it.
&lt;/p&gt;
&lt;h5&gt;It Worked for the First 10 Clients and then the Rest Timed Out!
&lt;/h5&gt;
&lt;p&gt;
Irrespective if which of the standard bindings you are using, duplex assumes a constant
relationship between proxy and service. In WCF this idea is modelled by the concept
of session. All duplex bindings require session. A while back &lt;a href="http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,af6e6325-2e30-42e3-acb9-57e1363fa51e.aspx"&gt;I
wrote in some detail about sessions&lt;/a&gt;. You will have to either put up with increasing
the session throttle (see the linked article for details) or roll your own custom
binding that can do duplex without session – you can find an example of this &lt;a href="http://blogs.msdn.com/ralph.squillace/archive/2006/10/10/Sessionless-duplex-services_3F00_-No-problem.-Small-issues_2C00_-yes_3B00_-problems_2C00_-no_2E00_.aspx"&gt;here&lt;/a&gt;.
&lt;/p&gt;
&lt;h5&gt;I Use the Callback While the Client is calling the Service and it Deadlocks!
&lt;/h5&gt;
&lt;p&gt;
This is because your client is probably a Rich Client GUI based application (Windows
Forms or WPF). To understand why this is a problem we need to step back briefly and
look at UI clients, threading and WCF threading. UI applications have a rule: you
must only update the UI from the thread that created those UI components. In general
a GUI application has one UI thread so anything that changes the UI needs to be done
from that thread. .NET 2.0 introduced a new construct to simplify the process of a
background thread updating the UI: SynchronizationContext. The idea is that a UI framework
creates an implementation of a SynchronizationContext derived class that handles the
mechanics of marshalling a call on to the UI thread. An instance of this implementation
is then made available on the UI and accessible via the SynchronizationContext.Current. 
&lt;/p&gt;
&lt;p&gt;
WCF adds more complexity into the mix by enforcing a rule that says “unless you tell
me otherwise I will only allow one thread at a time into an object that I control”.
You see this with singleton services that will only allow one call at a time by default.
The same is also true of the callback implementation object – so WCF will only allow
one active thread in the client at a time. So while WCF is performing an outbound
call it will not allow an inbound call into the object. This causes the initial problem
with the deadlock that the service’s callback cannot be dispatched while the client’s
outbound call is in progress. To solve this we use the “unless you tell me otherwise”
part of the above rule. You do this by annotating the callback implementation class
with a [CallbackBehavior] attribute like this:
&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;strong&gt;[CallbackBehavior(ConcurrencyMode=ConcurrencyMode.Reentrant)]&lt;/strong&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Callback
: IOrderPizzaCallback&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;{&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; TimeRemaining(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; minutes)&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    {&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        Console.WriteLine(&lt;span style="color: #006080"&gt;"{0}
seconds remaining"&lt;/span&gt;, minutes);&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    }&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; PizzaReady()&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    {&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        Console.WriteLine(&lt;span style="color: #006080"&gt;"Pizza
is ready"&lt;/span&gt;);&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    }&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;}&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
But now there is another problem: by default WCF will attempt to dispatch using an
available SynchronizationContext. The problem with this callback is the UI thread
is already blocked in an outbound call. SO for the call to dispatch we need to tell
WCF not to use the SynchronizationContext – again using the CallbackBehavior attribute:
&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;[CallbackBehavior(ConcurrencyMode=ConcurrencyMode.Reentrant, &lt;strong&gt;UseSynchronizationContext=&lt;span style="color: #0000ff"&gt;false&lt;/span&gt;&lt;/strong&gt;)]&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Callback
: IOrderPizzaCallback&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;{&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    ...&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;}&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
Now the issue is of course that the call is going to be processed on a non UI thread
so you would have to manually marshal any UI interaction using the SynchronizationContext.Post
method.
&lt;/p&gt;
&lt;p&gt;
Duplex messaging can be a useful message exchange pattern but in WCF there can be
some unexpected issues. Hopefully this blog post clarifies those issues and demonstrates
workarounds for them.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=b891610a-6b78-4b54-b9a6-4ec81c82b7c0" /&gt;</description>
      <comments>http://www.dotnetconsult.co.uk/weblog2/CommentView,guid,b891610a-6b78-4b54-b9a6-4ec81c82b7c0.aspx</comments>
      <category>.NET;Azure;WCF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=847c6d5c-4fcb-4271-8be9-61833877e8d1</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,847c6d5c-4fcb-4271-8be9-61833877e8d1.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <wfw:comment>http://www.dotnetconsult.co.uk/weblog2/CommentView,guid,847c6d5c-4fcb-4271-8be9-61833877e8d1.aspx</wfw:comment>
      <wfw:commentRss>http://www.dotnetconsult.co.uk/weblog2/SyndicationService.asmx/GetEntryCommentsRss?guid=847c6d5c-4fcb-4271-8be9-61833877e8d1</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <sigh>
it seems that the ever increasing immediacy of social networking and blogging has
some downsides. Ted Neward has posted a <a href="http://blogs.tedneward.com/CommentView,guid,dd85708f-48d8-47dc-a9c6-cc4a1287ad31.aspx#commentstart">eulogy</a> for
Developmentor (who I regularly teach for). Unfortunately Ted didn’t bother checking
his facts. DM are very much still in business and delivering courses (I’m teaching
one the week after next and the week after that in fact! Plus several in July and
September!)
</sigh>
        </p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=847c6d5c-4fcb-4271-8be9-61833877e8d1" />
      </body>
      <title>News of our death has been greatly exaggerated</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,847c6d5c-4fcb-4271-8be9-61833877e8d1.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,847c6d5c-4fcb-4271-8be9-61833877e8d1.aspx</link>
      <pubDate>Mon, 01 Jun 2009 18:29:26 GMT</pubDate>
      <description>&lt;p&gt;
&lt;sigh&gt;
it seems that the ever increasing immediacy of social networking and blogging has
some downsides. Ted Neward has posted a &lt;a href="http://blogs.tedneward.com/CommentView,guid,dd85708f-48d8-47dc-a9c6-cc4a1287ad31.aspx#commentstart"&gt;eulogy&lt;/a&gt; for
Developmentor (who I regularly teach for). Unfortunately Ted didn’t bother checking
his facts. DM are very much still in business and delivering courses (I’m teaching
one the week after next and the week after that in fact! Plus several in July and
September!)
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=847c6d5c-4fcb-4271-8be9-61833877e8d1" /&gt;</description>
      <comments>http://www.dotnetconsult.co.uk/weblog2/CommentView,guid,847c6d5c-4fcb-4271-8be9-61833877e8d1.aspx</comments>
      <category>.NET;Life</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=86b7d987-6db0-4da3-99fe-1c37a99a1715</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,86b7d987-6db0-4da3-99fe-1c37a99a1715.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <wfw:comment>http://www.dotnetconsult.co.uk/weblog2/CommentView,guid,86b7d987-6db0-4da3-99fe-1c37a99a1715.aspx</wfw:comment>
      <wfw:commentRss>http://www.dotnetconsult.co.uk/weblog2/SyndicationService.asmx/GetEntryCommentsRss?guid=86b7d987-6db0-4da3-99fe-1c37a99a1715</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
We’ve just posted a new screencast at <a href="http://rocksolidknowledge.com/">Rock
Solid Knowledge</a>. In this one I walk you through enabling WCF tracing to assist
in diagnosing bugs in your services using the example of a serialization failure.
You can find the screen casts here
</p>
        <p>
          <a href="http://rocksolidknowledge.com/ScreenCasts.mvc">http://rocksolidknowledge.com/ScreenCasts.mvc</a>
        </p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=86b7d987-6db0-4da3-99fe-1c37a99a1715" />
      </body>
      <title>New Screencast &amp;ndash; Using WCF Tracing for Debugging</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,86b7d987-6db0-4da3-99fe-1c37a99a1715.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,86b7d987-6db0-4da3-99fe-1c37a99a1715.aspx</link>
      <pubDate>Thu, 21 May 2009 11:22:42 GMT</pubDate>
      <description>&lt;p&gt;
We’ve just posted a new screencast at &lt;a href="http://rocksolidknowledge.com/"&gt;Rock
Solid Knowledge&lt;/a&gt;. In this one I walk you through enabling WCF tracing to assist
in diagnosing bugs in your services using the example of a serialization failure.
You can find the screen casts here
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://rocksolidknowledge.com/ScreenCasts.mvc"&gt;http://rocksolidknowledge.com/ScreenCasts.mvc&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=86b7d987-6db0-4da3-99fe-1c37a99a1715" /&gt;</description>
      <comments>http://www.dotnetconsult.co.uk/weblog2/CommentView,guid,86b7d987-6db0-4da3-99fe-1c37a99a1715.aspx</comments>
      <category>.NET;RSK;WCF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=2fee98c4-abb6-455e-a738-47f286bfaf51</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,2fee98c4-abb6-455e-a738-47f286bfaf51.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <wfw:comment>http://www.dotnetconsult.co.uk/weblog2/CommentView,guid,2fee98c4-abb6-455e-a738-47f286bfaf51.aspx</wfw:comment>
      <wfw:commentRss>http://www.dotnetconsult.co.uk/weblog2/SyndicationService.asmx/GetEntryCommentsRss?guid=2fee98c4-abb6-455e-a738-47f286bfaf51</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Every year I speak at the excellent <a href="http://www.devweek.com/">DevWeek</a> conference
in London. <a href="http://geekswithblogs.net/iupdateable/Default.aspx">Eric Nelson</a>,
a Microsoft Developer Evangelist in the UK is also a regular attendee. This year Eric, <a href="http://mtaulty.com/communityserver/blogs/mike_taultys_blog/default.aspx">Mike</a> and <a href="http://blogs.msdn.com/mikeormond/">Mike</a> were
recording interviews with people at the conference. Eric interviewed me about Workflow
4.0 (I was delivering a post conference day on WF 4.0, Dublin and Oslo). He’s just
got round to published it online
</p>
        <p>
          <a href="http://geekswithblogs.net/iupdateable/archive/2009/05/20/devweek-2009-interview-with-richard-blewett-on-workflow-4.0.aspx">http://geekswithblogs.net/iupdateable/archive/2009/05/20/devweek-2009-interview-with-richard-blewett-on-workflow-4.0.aspx</a>
        </p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=2fee98c4-abb6-455e-a738-47f286bfaf51" />
      </body>
      <title>DevWeek Interview Online</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,2fee98c4-abb6-455e-a738-47f286bfaf51.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,2fee98c4-abb6-455e-a738-47f286bfaf51.aspx</link>
      <pubDate>Thu, 21 May 2009 05:49:02 GMT</pubDate>
      <description>&lt;p&gt;
Every year I speak at the excellent &lt;a href="http://www.devweek.com/"&gt;DevWeek&lt;/a&gt; conference
in London. &lt;a href="http://geekswithblogs.net/iupdateable/Default.aspx"&gt;Eric Nelson&lt;/a&gt;,
a Microsoft Developer Evangelist in the UK is also a regular attendee. This year Eric, &lt;a href="http://mtaulty.com/communityserver/blogs/mike_taultys_blog/default.aspx"&gt;Mike&lt;/a&gt; and &lt;a href="http://blogs.msdn.com/mikeormond/"&gt;Mike&lt;/a&gt; were
recording interviews with people at the conference. Eric interviewed me about Workflow
4.0 (I was delivering a post conference day on WF 4.0, Dublin and Oslo). He’s just
got round to published it online
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://geekswithblogs.net/iupdateable/archive/2009/05/20/devweek-2009-interview-with-richard-blewett-on-workflow-4.0.aspx"&gt;http://geekswithblogs.net/iupdateable/archive/2009/05/20/devweek-2009-interview-with-richard-blewett-on-workflow-4.0.aspx&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=2fee98c4-abb6-455e-a738-47f286bfaf51" /&gt;</description>
      <comments>http://www.dotnetconsult.co.uk/weblog2/CommentView,guid,2fee98c4-abb6-455e-a738-47f286bfaf51.aspx</comments>
      <category>.NET;Dublin;Oslo;WF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=06c841b2-52b8-473a-8168-b063b3a24b34</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,06c841b2-52b8-473a-8168-b063b3a24b34.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <wfw:comment>http://www.dotnetconsult.co.uk/weblog2/CommentView,guid,06c841b2-52b8-473a-8168-b063b3a24b34.aspx</wfw:comment>
      <wfw:commentRss>http://www.dotnetconsult.co.uk/weblog2/SyndicationService.asmx/GetEntryCommentsRss?guid=06c841b2-52b8-473a-8168-b063b3a24b34</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Soma has blogged that beta 1 has finally shipped. Lots of new stuff in here since
PDC. His blog post is here
</p>
        <p>
          <a href="http://blogs.msdn.com/somasegar/archive/2009/05/18/visual-studio-2010-and-net-fx-4-beta-1-ships.aspx">http://blogs.msdn.com/somasegar/archive/2009/05/18/visual-studio-2010-and-net-fx-4-beta-1-ships.aspx</a>
        </p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=06c841b2-52b8-473a-8168-b063b3a24b34" />
      </body>
      <title>Visual Studio 2010 Beta 1 Ships</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,06c841b2-52b8-473a-8168-b063b3a24b34.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,06c841b2-52b8-473a-8168-b063b3a24b34.aspx</link>
      <pubDate>Mon, 18 May 2009 15:06:32 GMT</pubDate>
      <description>&lt;p&gt;
Soma has blogged that beta 1 has finally shipped. Lots of new stuff in here since
PDC. His blog post is here
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blogs.msdn.com/somasegar/archive/2009/05/18/visual-studio-2010-and-net-fx-4-beta-1-ships.aspx"&gt;http://blogs.msdn.com/somasegar/archive/2009/05/18/visual-studio-2010-and-net-fx-4-beta-1-ships.aspx&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=06c841b2-52b8-473a-8168-b063b3a24b34" /&gt;</description>
      <comments>http://www.dotnetconsult.co.uk/weblog2/CommentView,guid,06c841b2-52b8-473a-8168-b063b3a24b34.aspx</comments>
      <category>.NET;WCF;WF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=6b977408-c307-4ba1-9774-3fdeead0521c</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,6b977408-c307-4ba1-9774-3fdeead0521c.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <wfw:comment>http://www.dotnetconsult.co.uk/weblog2/CommentView,guid,6b977408-c307-4ba1-9774-3fdeead0521c.aspx</wfw:comment>
      <wfw:commentRss>http://www.dotnetconsult.co.uk/weblog2/SyndicationService.asmx/GetEntryCommentsRss?guid=6b977408-c307-4ba1-9774-3fdeead0521c</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
We’ve started a library of screencasts at <a href="http://rocksolidknowledge.com/">rock
solid knowledge</a>. I’ve created one on WCF Serialization and one on using SSL with
Self hosted WCF services. <a href="http://andyclymer.blogspot.com/">Andy Clymer</a> has
recorded one on Visual Studio Tricks and Tips and Dave Wheeler has one on character
animation in Silverlight 2.0. You can find the screen casts at
</p>
        <p>
          <a href="http://rocksolidknowledge.com/ScreenCasts.mvc">http://rocksolidknowledge.com/ScreenCasts.mvc</a>
        </p>
        <p>
We’ll be adding to the library as time goes on so subscribe to the library RSS feed
</p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=6b977408-c307-4ba1-9774-3fdeead0521c" />
      </body>
      <title>New Screencasts at Rocksolidknowledge.com</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,6b977408-c307-4ba1-9774-3fdeead0521c.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,6b977408-c307-4ba1-9774-3fdeead0521c.aspx</link>
      <pubDate>Mon, 18 May 2009 10:50:15 GMT</pubDate>
      <description>&lt;p&gt;
We’ve started a library of screencasts at &lt;a href="http://rocksolidknowledge.com/"&gt;rock
solid knowledge&lt;/a&gt;. I’ve created one on WCF Serialization and one on using SSL with
Self hosted WCF services. &lt;a href="http://andyclymer.blogspot.com/"&gt;Andy Clymer&lt;/a&gt; has
recorded one on Visual Studio Tricks and Tips and Dave Wheeler has one on character
animation in Silverlight 2.0. You can find the screen casts at
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://rocksolidknowledge.com/ScreenCasts.mvc"&gt;http://rocksolidknowledge.com/ScreenCasts.mvc&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
We’ll be adding to the library as time goes on so subscribe to the library RSS feed
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=6b977408-c307-4ba1-9774-3fdeead0521c" /&gt;</description>
      <comments>http://www.dotnetconsult.co.uk/weblog2/CommentView,guid,6b977408-c307-4ba1-9774-3fdeead0521c.aspx</comments>
      <category>.NET;RSK;SilverLight;WCF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=ac27a12b-23a9-4154-b3e1-4c1c27e26c1e</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,ac27a12b-23a9-4154-b3e1-4c1c27e26c1e.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <wfw:comment>http://www.dotnetconsult.co.uk/weblog2/CommentView,guid,ac27a12b-23a9-4154-b3e1-4c1c27e26c1e.aspx</wfw:comment>
      <wfw:commentRss>http://www.dotnetconsult.co.uk/weblog2/SyndicationService.asmx/GetEntryCommentsRss?guid=ac27a12b-23a9-4154-b3e1-4c1c27e26c1e</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Cliff Simpkins has just <a href="http://blogs.msdn.com/endpoint/archive/2009/05/01/the-road-to-4-wf-changes-between-beta-1-and-ctp.aspx">posted
a blog entry</a> detailing some of the changes between the PDC preview of WF 4.0 and
what is coming in beta 1, due shortly. 
</p>
        <p>
Important information here not just about beta 1 but also about things you can expect
and also things that won’t make it into RTM
</p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=ac27a12b-23a9-4154-b3e1-4c1c27e26c1e" />
      </body>
      <title>What&amp;rsquo;s new in WF 4.0 Beta 1</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,ac27a12b-23a9-4154-b3e1-4c1c27e26c1e.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,ac27a12b-23a9-4154-b3e1-4c1c27e26c1e.aspx</link>
      <pubDate>Fri, 01 May 2009 23:27:00 GMT</pubDate>
      <description>&lt;p&gt;
Cliff Simpkins has just &lt;a href="http://blogs.msdn.com/endpoint/archive/2009/05/01/the-road-to-4-wf-changes-between-beta-1-and-ctp.aspx"&gt;posted
a blog entry&lt;/a&gt; detailing some of the changes between the PDC preview of WF 4.0 and
what is coming in beta 1, due shortly. 
&lt;/p&gt;
&lt;p&gt;
Important information here not just about beta 1 but also about things you can expect
and also things that won’t make it into RTM
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=ac27a12b-23a9-4154-b3e1-4c1c27e26c1e" /&gt;</description>
      <comments>http://www.dotnetconsult.co.uk/weblog2/CommentView,guid,ac27a12b-23a9-4154-b3e1-4c1c27e26c1e.aspx</comments>
      <category>.NET;WCF;WF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=2ce96651-c153-416a-a680-cced6ee34fdd</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,2ce96651-c153-416a-a680-cced6ee34fdd.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <wfw:comment>http://www.dotnetconsult.co.uk/weblog2/CommentView,guid,2ce96651-c153-416a-a680-cced6ee34fdd.aspx</wfw:comment>
      <wfw:commentRss>http://www.dotnetconsult.co.uk/weblog2/SyndicationService.asmx/GetEntryCommentsRss?guid=2ce96651-c153-416a-a680-cced6ee34fdd</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I’ve been doing some work with the <a href="http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=24644">WCF
REST Starter Kit</a> for our website <a href="http://rocksolidknowledge.com">http://rocksolidknowledge.com</a>.
Preview 2 of the start kit has a bunch of client side plumbing (the original release
concentrated on the service side)
</p>
        <p>
The client side code looks something like this:
</p>
        <p>
          <font size="2">
            <font face="Courier New">
              <font color="#2b91af">
                <font color="#2b91af">HttpClient</font>
              </font> client
= <font color="#0000ff"><font color="#0000ff">new</font></font><font color="#2b91af"><font color="#2b91af">HttpClient</font></font>(<font color="#a31515"><font color="#a31515">"http://twitter.com"</font></font>);</font>
          </font>
        </p>
        <p>
          <font size="2">
            <font face="Courier New">
              <font color="#2b91af">
                <font color="#2b91af">HttpResponseMessage</font>
              </font> response
= client.Get(<font color="#a31515"><font color="#a31515">"statuses/user_timeline/richardblewett.xml"</font></font>);</font>
          </font>
        </p>
        <p>
          <font size="2">
            <font face="Courier New">
              <font color="#2b91af">
                <font color="#2b91af">Console</font>
              </font>.WriteLine(response.Content.ReadAsString());</font>
          </font>
        </p>
        <p>
          <font size="2">As compact as this is I was a bit disappointed to see that I only had
a few options for processing the content: <font face="Courier New">ReadAsString</font>, <font face="Courier New">ReadAsStream</font> and <font face="Courier New">ReadAsByteArray</font>.
Now seeing as they had a free hand to give you all sorts of processing options I was
surprised there weren’t more. However, one of the assemblies with the start kit is
called <font face="Courier New">Microsoft.Http.Extensions</font>. So I opened it up
in <a href="http://www.red-gate.com/products/reflector/">Reflector</a> and lo and
behold there are a whole bunch of extension methods in there – so why wasn’t I seeing
them? </font>
        </p>
        <p>
          <font size="2">Extension methods become available to your code when their namespace
is in scope (e.g. when you have a using statement for the namespace in your code).
It turns out that the team put the extension methods in the namespaces appropriate
to the technology they were exposing. So for example the <font face="Courier New">ReadAsXElement</font> extension
method is in the <font face="Courier New">System.Xml.Linq</font> namespace and the <font face="Courier New">ReadAsXmlSerializable&lt;T&gt;</font> method
is in the <font face="Courier New">System.Xml.Serialization</font> namespace.</font>
        </p>
        <p>
          <font size="2">Although I really like the functionality of the WCF Starter Kit, this
particular practice, to me, seems bizarre. Firstly, it makes the API counter intuitive
– you use the HttpClient class and then there is no hint in the library that there
are a bunch of hidden extensions. Secondly, injecting your extensions into someone
else’s namespace increases the likelihood of extension method collision (where two
libraries define the same extension method in the same namespace). The same named
extension method in difference namespaces can be disambiguated, the same named extension
in the same namespace gives you no chance.</font>
        </p>
        <p>
          <font size="2">I think if you want to define extension methods then you should keep
them in your own namespace – it makes everyone’s life simpler in the long run.</font>
        </p>
        <p>
          <font size="2">
          </font>
        </p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=2ce96651-c153-416a-a680-cced6ee34fdd" />
      </body>
      <title>Extension Methods and Good Practice &amp;ndash; or OI! Get Out of my Namespace!</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,2ce96651-c153-416a-a680-cced6ee34fdd.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,2ce96651-c153-416a-a680-cced6ee34fdd.aspx</link>
      <pubDate>Sun, 05 Apr 2009 15:58:48 GMT</pubDate>
      <description>&lt;p&gt;
I’ve been doing some work with the &lt;a href="http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=24644"&gt;WCF
REST Starter Kit&lt;/a&gt; for our website &lt;a href="http://rocksolidknowledge.com"&gt;http://rocksolidknowledge.com&lt;/a&gt;.
Preview 2 of the start kit has a bunch of client side plumbing (the original release
concentrated on the service side)
&lt;/p&gt;
&lt;p&gt;
The client side code looks something like this:
&lt;/p&gt;
&lt;p&gt;
&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;font color="#2b91af"&gt;&lt;font color="#2b91af"&gt;HttpClient&lt;/font&gt;&lt;/font&gt; client
= &lt;font color="#0000ff"&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;/font&gt; &lt;font color="#2b91af"&gt;&lt;font color="#2b91af"&gt;HttpClient&lt;/font&gt;&lt;/font&gt;(&lt;font color="#a31515"&gt;&lt;font color="#a31515"&gt;"http://twitter.com"&lt;/font&gt;&lt;/font&gt;);&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;font color="#2b91af"&gt;&lt;font color="#2b91af"&gt;HttpResponseMessage&lt;/font&gt;&lt;/font&gt; response
= client.Get(&lt;font color="#a31515"&gt;&lt;font color="#a31515"&gt;"statuses/user_timeline/richardblewett.xml"&lt;/font&gt;&lt;/font&gt;);&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;font color="#2b91af"&gt;&lt;font color="#2b91af"&gt;Console&lt;/font&gt;&lt;/font&gt;.WriteLine(response.Content.ReadAsString());&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font size="2"&gt;As compact as this is I was a bit disappointed to see that I only had
a few options for processing the content: &lt;font face="Courier New"&gt;ReadAsString&lt;/font&gt;, &lt;font face="Courier New"&gt;ReadAsStream&lt;/font&gt; and &lt;font face="Courier New"&gt;ReadAsByteArray&lt;/font&gt;.
Now seeing as they had a free hand to give you all sorts of processing options I was
surprised there weren’t more. However, one of the assemblies with the start kit is
called &lt;font face="Courier New"&gt;Microsoft.Http.Extensions&lt;/font&gt;. So I opened it up
in &lt;a href="http://www.red-gate.com/products/reflector/"&gt;Reflector&lt;/a&gt; and lo and
behold there are a whole bunch of extension methods in there – so why wasn’t I seeing
them? &lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font size="2"&gt;Extension methods become available to your code when their namespace
is in scope (e.g. when you have a using statement for the namespace in your code).
It turns out that the team put the extension methods in the namespaces appropriate
to the technology they were exposing. So for example the &lt;font face="Courier New"&gt;ReadAsXElement&lt;/font&gt; extension
method is in the &lt;font face="Courier New"&gt;System.Xml.Linq&lt;/font&gt; namespace and the &lt;font face="Courier New"&gt;ReadAsXmlSerializable&amp;lt;T&amp;gt;&lt;/font&gt; method
is in the &lt;font face="Courier New"&gt;System.Xml.Serialization&lt;/font&gt; namespace.&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font size="2"&gt;Although I really like the functionality of the WCF Starter Kit, this
particular practice, to me, seems bizarre. Firstly, it makes the API counter intuitive
– you use the HttpClient class and then there is no hint in the library that there
are a bunch of hidden extensions. Secondly, injecting your extensions into someone
else’s namespace increases the likelihood of extension method collision (where two
libraries define the same extension method in the same namespace). The same named
extension method in difference namespaces can be disambiguated, the same named extension
in the same namespace gives you no chance.&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font size="2"&gt;I think if you want to define extension methods then you should keep
them in your own namespace – it makes everyone’s life simpler in the long run.&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font size="2"&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=2ce96651-c153-416a-a680-cced6ee34fdd" /&gt;</description>
      <comments>http://www.dotnetconsult.co.uk/weblog2/CommentView,guid,2ce96651-c153-416a-a680-cced6ee34fdd.aspx</comments>
      <category>.NET;REST;WCF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=db4d4d38-b469-4181-aead-f8de85f39b80</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,db4d4d38-b469-4181-aead-f8de85f39b80.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <wfw:comment>http://www.dotnetconsult.co.uk/weblog2/CommentView,guid,db4d4d38-b469-4181-aead-f8de85f39b80.aspx</wfw:comment>
      <wfw:commentRss>http://www.dotnetconsult.co.uk/weblog2/SyndicationService.asmx/GetEntryCommentsRss?guid=db4d4d38-b469-4181-aead-f8de85f39b80</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Thanks all who attended my post conference day on a day of connected systems with
.NET 4.0, Dublin and Oslo. You can get the demos <a href="http://rocksolidknowledge.blob.core.windows.net/demos/Devweek2009DayOfCSD.zip">here</a>.
</p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=db4d4d38-b469-4181-aead-f8de85f39b80" />
      </body>
      <title>Devweek 2009: A Day Connected Systems Demos</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,db4d4d38-b469-4181-aead-f8de85f39b80.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,db4d4d38-b469-4181-aead-f8de85f39b80.aspx</link>
      <pubDate>Sat, 28 Mar 2009 08:39:03 GMT</pubDate>
      <description>&lt;p&gt;
Thanks all who attended my post conference day on a day of connected systems with
.NET 4.0, Dublin and Oslo. You can get the demos &lt;a href="http://rocksolidknowledge.blob.core.windows.net/demos/Devweek2009DayOfCSD.zip"&gt;here&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=db4d4d38-b469-4181-aead-f8de85f39b80" /&gt;</description>
      <comments>http://www.dotnetconsult.co.uk/weblog2/CommentView,guid,db4d4d38-b469-4181-aead-f8de85f39b80.aspx</comments>
      <category>Dublin;Oslo;WCF;WF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=76bd58e0-39e7-4624-b3af-b6794d047cef</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,76bd58e0-39e7-4624-b3af-b6794d047cef.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <wfw:comment>http://www.dotnetconsult.co.uk/weblog2/CommentView,guid,76bd58e0-39e7-4624-b3af-b6794d047cef.aspx</wfw:comment>
      <wfw:commentRss>http://www.dotnetconsult.co.uk/weblog2/SyndicationService.asmx/GetEntryCommentsRss?guid=76bd58e0-39e7-4624-b3af-b6794d047cef</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Thanks to all who attended my <a href="www.devweek.com">Devweek</a> session: A Beginners
Guide to Windows Workflow. The slides and demos can be downloaded <a href="http://dotnetconsult.blob.core.windows.net/demos/WorkflowForBeginners.zip">here</a></p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=76bd58e0-39e7-4624-b3af-b6794d047cef" />
      </body>
      <title>Slides and demos from my Windows Workflow Session at Devweek</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,76bd58e0-39e7-4624-b3af-b6794d047cef.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,76bd58e0-39e7-4624-b3af-b6794d047cef.aspx</link>
      <pubDate>Thu, 26 Mar 2009 06:51:37 GMT</pubDate>
      <description>&lt;p&gt;
Thanks to all who attended my &lt;a href="www.devweek.com"&gt;Devweek&lt;/a&gt; session: A Beginners
Guide to Windows Workflow. The slides and demos can be downloaded &lt;a href="http://dotnetconsult.blob.core.windows.net/demos/WorkflowForBeginners.zip"&gt;here&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=76bd58e0-39e7-4624-b3af-b6794d047cef" /&gt;</description>
      <comments>http://www.dotnetconsult.co.uk/weblog2/CommentView,guid,76bd58e0-39e7-4624-b3af-b6794d047cef.aspx</comments>
      <category>.NET;WF</category>
    </item>
  </channel>
</rss>