<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>David Kline : Windows Communication Foundation</title><link>http://blogs.msdn.com/davidklinems/archive/tags/Windows+Communication+Foundation/default.aspx</link><description>Tags: Windows Communication Foundation</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>The Journey of the Lunch Launcher: Part 6 - Processing messages</title><link>http://blogs.msdn.com/davidklinems/archive/2007/10/17/the-journey-of-the-lunch-launcher-part-6-processing-messages.aspx</link><pubDate>Wed, 17 Oct 2007 23:07:41 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5498318</guid><dc:creator>DavidKlineMS</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/davidklinems/comments/5498318.aspx</comments><wfw:commentRss>http://blogs.msdn.com/davidklinems/commentrss.aspx?PostID=5498318</wfw:commentRss><description>&lt;p&gt;&lt;a href="http://blogs.msdn.com/davidklinems/archive/2007/09/07/the-journey-of-the-lunch-launcher-part-1-the-origins-of-the-lunch-launcher.aspx"&gt;Part 1 - The origins of the 'lunch launcher'&lt;/a&gt;&lt;br&gt;&lt;a href="http://blogs.msdn.com/davidklinems/archive/2007/09/10/the-journey-of-the-lunch-launcher-part-2-medc-2007.aspx"&gt;Part 2 - MEDC 2007&lt;/a&gt;&lt;br&gt;&lt;a href="http://blogs.msdn.com/davidklinems/archive/2007/09/11/the-journey-of-the-lunch-launcher-part-3-managing-the-transport.aspx"&gt;Part 3 - Managing the Transport&lt;/a&gt;&lt;br&gt;&lt;a href="http://blogs.msdn.com/davidklinems/archive/2007/09/28/the-journey-of-the-lunch-launcher-part-4-sending-messages.aspx"&gt;Part 4 - Sending messages&lt;/a&gt;&lt;br&gt;&lt;a href="http://blogs.msdn.com/davidklinems/archive/2007/10/03/the-journey-of-the-lunch-launcher-part-4b-the-output-channel.aspx"&gt;Part 4b - The output channel&lt;/a&gt;&lt;br&gt;&lt;a href="http://blogs.msdn.com/davidklinems/archive/2007/10/12/the-journey-of-the-lunch-launcher-part-5-receiving-and-processing-messages.aspx"&gt;Part 5 - Receiving messages&lt;/a&gt;&lt;br&gt;&lt;br&gt;Last time, I talked about &lt;a href="http://blogs.msdn.com/davidklinems/archive/2007/10/12/the-journey-of-the-lunch-launcher-part-5-receiving-and-processing-messages.aspx"&gt;how the Lunch Launcher receives messages&lt;/a&gt;.&amp;nbsp; Today's topic is now the messages are processed.&lt;br&gt;&lt;br&gt;As with all entries in this series, please note that the following disclaimer covers all examples contained herein.&lt;br&gt;&lt;code&gt;&lt;br&gt;//-----------------------------------------------------------------------&lt;br&gt;//THIS CODE AND INFORMATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY&lt;br&gt;//KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE&lt;br&gt;//IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A&lt;br&gt;//PARTICULAR PURPOSE.&lt;br&gt;//-----------------------------------------------------------------------&lt;br&gt;&lt;/code&gt;&lt;br&gt;&lt;strong&gt;MEDC 2007&lt;br&gt;&lt;/strong&gt;Just like the listeners, the MEDC 2007 version of the Lunch Launcher demo contained three nearly identical processing methods. &lt;br&gt;&lt;code&gt;&lt;br&gt;/// &amp;lt;summary&amp;gt;&lt;br&gt;/// Processes a received lunch invitation&lt;br&gt;/// &amp;lt;/summary&amp;gt;&lt;br&gt;/// &amp;lt;param name="msg"&amp;gt;&lt;br&gt;/// The lunch invitation message&lt;br&gt;/// &amp;lt;/param&amp;gt;&lt;br&gt;/// &amp;lt;param name="from"&amp;gt;&lt;br&gt;/// The email address of the sender&lt;br&gt;/// &amp;lt;/param&amp;gt;&lt;br&gt;private void ProcessInvitation(Message msg, String from)&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; LunchObjectSerializer serializer = &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new LunchObjectSerializer(typeof(LunchInvitation));&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // get the buddy who sent the invitation&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Buddy buddy = LookupBuddy(from);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // ignore invitations from those who&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&amp;nbsp; are not in the buddy list&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(null != buddy)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // get the invitation&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; LunchInvitation invitation = &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; msg.GetBody&amp;lt;LunchInvitation&amp;gt;(serializer);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // notified registered event handlers&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SendInvitationReceived(&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new InvitationReceivedEventArgs(buddy, invitation));&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;}&lt;br&gt;&lt;/code&gt;&lt;br&gt;When a message is processed, the method creates a serializer for the LunchInvitation object to be used when the message body is extracted.&lt;br&gt;&lt;br&gt;Next, the sender of the invitation is compared with the user's buddy list.&amp;nbsp; This is done to avoid unsolicited invitations from people with whom the user would rather not have lunch.&lt;br&gt;&lt;br&gt;If the sender is found in the buddy list, the message body is retrieved and the user interface is notified.&amp;nbsp; When the user interface handles the event, it presents the user with a 'you have been invited' form.&lt;br&gt;&lt;br&gt;&lt;strong&gt;Current version&lt;/strong&gt;&lt;br&gt;In the current version (October 2007), the processing methods have been consolidated into a single generic method. &lt;br&gt;&lt;code&gt;&lt;br&gt;/// &amp;lt;summary&amp;gt;&lt;br&gt;/// Process a received message&lt;br&gt;/// &amp;lt;/summary&amp;gt;&lt;br&gt;/// &amp;lt;typeparam name="T"&amp;gt;&lt;br&gt;/// The type of object contained within the message&lt;br&gt;/// &amp;lt;/typeparam&amp;gt;&lt;br&gt;/// &amp;lt;param name="msg"&amp;gt;&lt;br&gt;/// The lunch invitation message&lt;br&gt;/// &amp;lt;/param&amp;gt;&lt;br&gt;/// &amp;lt;param name="from"&amp;gt;&lt;br&gt;/// The email address of the sender&lt;br&gt;/// &amp;lt;/param&amp;gt;&lt;br&gt;private void ProcessMessage&amp;lt;T&amp;gt;(Message msg, String from)&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // get the buddy who sent the message&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Buddy buddy = LookupBuddy(from);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // ignore invitations from those who&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&amp;nbsp; are not in the buddy list&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(null != buddy)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // get the serializer&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; LunchObjectSerializer serializer = GetSerializer&amp;lt;T&amp;gt;();&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // get the invitation&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; T payload = msg.GetBody&amp;lt;T&amp;gt;(serializer);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // notified registered event handlers&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SendMessageReceived(&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new LunchLauncherMessageReceivedEventArgs&amp;lt;T&amp;gt;(buddy, payload));&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;}&lt;br&gt;&lt;/code&gt;&lt;br&gt;There are a few changes to this version.&amp;nbsp; First, like last time's example, the serializer is retrieved from a class-global collection.&amp;nbsp; This saves on reflection costs and reduces the amount garbage generated as the application receives messages.&lt;br&gt;&lt;br&gt;The second change is the consolidation of the event handlers into a generic method.&amp;nbsp; As I was reviewing the code right after my session, I took notes on the areas where code was highly similar.&amp;nbsp; Wherever possible, I merged the methods into generic versions.&amp;nbsp; This has resulted in much less code to review :) and fewer issues to investigate.&amp;nbsp; Fixing once is much better than fixing multiple times, or worse yet, forgetting to apply the fix to one of the duplicates.&lt;br&gt;&lt;br&gt;Lastly, I moved the serializer retrieval into the conditional block.&amp;nbsp; There is no need to fetch it unless we recognize the sender of the message -- a very small performance increase.&lt;br&gt;&lt;br&gt;&lt;strong&gt;In closing&lt;/strong&gt;&lt;br&gt;We are getting towards the end of this series -- there are only a couple more topics that I would like to cover.&amp;nbsp; I hope you are enjoying reading about my experiences writing the Lunch Launcher demo.&amp;nbsp; As I mentioned last time, as I continue to work on the demo, I plan on keeping the examples in this series fresh.&amp;nbsp; This will likely result in edits (read: extensions) to the posts in this series.&amp;nbsp; As I make changes, I will post a topic pointing them out.&lt;br&gt;&lt;br&gt;Next up, a look at the 'lunch manager'.&lt;br&gt;&lt;br&gt;Take care,&lt;br&gt;-- DK&lt;br&gt;&lt;br&gt;&lt;font face="Arial" size="1"&gt;Disclaimer(s):&lt;br&gt;This posting is provided "AS IS" with no warranties, and confers no rights.&lt;br&gt;The information contained within this post is in relation to beta software.&amp;nbsp; Any and all details are subject to change.&lt;/font&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5498318" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/davidklinems/archive/tags/Windows+Communication+Foundation/default.aspx">Windows Communication Foundation</category></item><item><title>The Journey of the Lunch Launcher - Part 5: Receiving messages</title><link>http://blogs.msdn.com/davidklinems/archive/2007/10/12/the-journey-of-the-lunch-launcher-part-5-receiving-and-processing-messages.aspx</link><pubDate>Fri, 12 Oct 2007 22:21:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5427375</guid><dc:creator>DavidKlineMS</dc:creator><slash:comments>8</slash:comments><comments>http://blogs.msdn.com/davidklinems/comments/5427375.aspx</comments><wfw:commentRss>http://blogs.msdn.com/davidklinems/commentrss.aspx?PostID=5427375</wfw:commentRss><description>&lt;P&gt;&lt;A href="http://blogs.msdn.com/davidklinems/archive/2007/09/07/the-journey-of-the-lunch-launcher-part-1-the-origins-of-the-lunch-launcher.aspx" mce_href="http://blogs.msdn.com/davidklinems/archive/2007/09/07/the-journey-of-the-lunch-launcher-part-1-the-origins-of-the-lunch-launcher.aspx"&gt;Part 1 - The origins of the 'lunch launcher'&lt;/A&gt;&lt;BR&gt;&lt;A href="http://blogs.msdn.com/davidklinems/archive/2007/09/10/the-journey-of-the-lunch-launcher-part-2-medc-2007.aspx" mce_href="http://blogs.msdn.com/davidklinems/archive/2007/09/10/the-journey-of-the-lunch-launcher-part-2-medc-2007.aspx"&gt;Part 2 - MEDC 2007&lt;/A&gt;&lt;BR&gt;&lt;A href="http://blogs.msdn.com/davidklinems/archive/2007/09/11/the-journey-of-the-lunch-launcher-part-3-managing-the-transport.aspx" mce_href="http://blogs.msdn.com/davidklinems/archive/2007/09/11/the-journey-of-the-lunch-launcher-part-3-managing-the-transport.aspx"&gt;Part 3 - Managing the Transport&lt;/A&gt;&lt;BR&gt;&lt;A href="http://blogs.msdn.com/davidklinems/archive/2007/09/28/the-journey-of-the-lunch-launcher-part-4-sending-messages.aspx" mce_href="http://blogs.msdn.com/davidklinems/archive/2007/09/28/the-journey-of-the-lunch-launcher-part-4-sending-messages.aspx"&gt;Part 4 - Sending messages&lt;/A&gt;&lt;BR&gt;&lt;A href="http://blogs.msdn.com/davidklinems/archive/2007/10/03/the-journey-of-the-lunch-launcher-part-4b-the-output-channel.aspx" mce_href="http://blogs.msdn.com/davidklinems/archive/2007/10/03/the-journey-of-the-lunch-launcher-part-4b-the-output-channel.aspx"&gt;Part 4b - The output channel&lt;/A&gt;&lt;BR&gt;&lt;BR&gt;In the series so far, we have seen how the Lunch Launcher manages the Store and Forward Messaging transport objects and how it sends messages (invitations, replies) to buddies.&amp;nbsp; Now, it's time to see how the messages are received.&lt;BR&gt;&lt;BR&gt;As with all entries in this series, please note that the following disclaimer covers all examples contained herein.&lt;BR&gt;&lt;CODE&gt;&lt;BR&gt;//-----------------------------------------------------------------------&lt;BR&gt;//THIS CODE AND INFORMATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY&lt;BR&gt;//KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE&lt;BR&gt;//IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A&lt;BR&gt;//PARTICULAR PURPOSE.&lt;BR&gt;//-----------------------------------------------------------------------&lt;BR&gt;&lt;/CODE&gt;&lt;BR&gt;When the Lunch Launcher starts, it creates three child threads to listen for incoming messages.&amp;nbsp; The details of how these listeners are managed will be discussed in a future post.&lt;BR&gt;&lt;BR&gt;As mentioned previously, when I was first writing the Lunch Launcher to show at MEDC 2007, code optimizations were not my primary concern.&amp;nbsp; The code had been written so that it was easy to describe in a big room (~400 people) during an introductory (200 level) session.&amp;nbsp; As such, there was a significant amount of near-exact duplication.&lt;BR&gt;&lt;BR&gt;&lt;STRONG&gt;MEDC 2007&lt;/STRONG&gt;&lt;BR&gt;Let's start by taking a look at the original demo code (circa May 2007).&amp;nbsp; Given the level of similarity between each of the listeners, we will look only at how lunch invitations are received.&lt;BR&gt;&lt;CODE&gt;&lt;BR&gt;/// &amp;lt;summary&amp;gt;&lt;BR&gt;/// Receive lunch invitation messages&lt;BR&gt;/// &amp;lt;/summary&amp;gt;&lt;BR&gt;private void InvitationListener(Object state)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Thread.CurrentThread.Name = "LunchManager - Invitation Listener";&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; TimeSpan timeout = new TimeSpan(0, 0, 0, 0, this.m_ReceiveTimeout);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.m_InvitationTransportObjects = new TransportObjects(InviteChannelName);&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; try&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // initialize the transport objects&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.m_InvitationTransportObjects.Initialize();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Boolean keepRunning = true;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; while(keepRunning)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IInputChannel channel = &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.m_InvitationTransportObjects.InputChannel;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // wait for an invitation&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Message msg = channel.Receive(timeout);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(null != msg)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // there is a message to process&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // get the sender's email address&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; String from = (String)msg.Properties["FromEmailAddress"];&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // process the message&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ProcessInvitation(msg, from);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // there is no message to process&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // determine why we did not receive a message&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; switch(channel.State)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // transport faulted&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; case CommunicationState.Faulted:&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // attempt to recover from the fault&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; keepRunning = this.m_InvitationTransportObjects.Recover();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // channel is closing/closed&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; case CommunicationState.Closing:&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; case CommunicationState.Closed:&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // unexpected state&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; default:&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; catch(TimeoutException)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { /* there was nothing to receive */ }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; catch(CommunicationException)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // failure communicating with the service&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&amp;nbsp; sleep for awhile to allow it to recover&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Thread.Sleep(timeout.Milliseconds);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; catch&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // fatal error&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; keepRunning = false;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; catch&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { /* fatal error */ }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; finally&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // uninitialize the transport objects&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.m_InvitationTransportObjects.Uninitialize();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;}&lt;BR&gt;&lt;/CODE&gt;&lt;BR&gt;Here we have a pretty straight forward listener thread delegate.&amp;nbsp; Each loop iteration, it checks to see if it should stop and if not, try to receive a message.&amp;nbsp; Once received (msg != null), the message is passed to a processing method (to be talked about next time).&amp;nbsp; If the transport faults (&lt;A href="http://msdn2.microsoft.com/en-us/library/system.servicemodel.communicationstate.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/system.servicemodel.communicationstate.aspx"&gt;CommunicationState&lt;/A&gt;.Faulted), we attempt a recovery.&amp;nbsp;&amp;nbsp; On a &lt;A href="http://msdn2.microsoft.com/en-us/library/system.servicemodel.communicationexception.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/system.servicemodel.communicationexception.aspx"&gt;CommunicationException&lt;/A&gt;, we pause for a few seconds and resume receiving.&lt;BR&gt;&lt;BR&gt;Did you see the problem when the channel is closed?&amp;nbsp; On &lt;A href="http://msdn2.microsoft.com/en-us/library/system.servicemodel.communicationstate.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/system.servicemodel.communicationstate.aspx"&gt;CommunicationState&lt;/A&gt;.Closing and &lt;A href="http://msdn2.microsoft.com/en-us/library/system.servicemodel.communicationstate.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/system.servicemodel.communicationstate.aspx"&gt;CommunicationState&lt;/A&gt;.Closed, the loop retries and falls into the same path.&amp;nbsp; The reason this originally went unnoticed is that the InvitationListener is a background thread (started via &lt;A href="http://msdn2.microsoft.com/en-us/library/system.threading.threadpool.queueuserworkitem.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/system.threading.threadpool.queueuserworkitem.aspx"&gt;ThreadPool.QueueUserWorkitem&lt;/A&gt;).&amp;nbsp; Background threads are terminated when the main thread exits, so I missed the bug.&lt;BR&gt;&lt;BR&gt;&lt;STRONG&gt;Current version&lt;/STRONG&gt;&lt;BR&gt;Since returning from MEDC, I have made some significant changes to the listeners.&amp;nbsp; Most importantly, I have consolidated the code so that there is little, if any direct duplication.&amp;nbsp; This reduction in duplicate code allows bugs found in one listener to be fixed in the other two automatically, as evidenced by the example above.&lt;BR&gt;&lt;BR&gt;Let's take a look at the current (October 2007) version.&amp;nbsp; I'll start by showing all of the thread delegates.&lt;BR&gt;&lt;CODE&gt;&lt;BR&gt;/// &amp;lt;summary&amp;gt;&lt;BR&gt;/// Receive lunch invitation messages&lt;BR&gt;/// &amp;lt;/summary&amp;gt;&lt;BR&gt;private void InvitationListener(Object state)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Thread.CurrentThread.Name = "LunchManager - Invitation Listener";&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Listen&amp;lt;LunchInvitation&amp;gt;(this.WaitMilliseconds);&lt;BR&gt;}&lt;BR&gt;&lt;BR&gt;/// &amp;lt;summary&amp;gt;&lt;BR&gt;/// Receive lunch invitation reply messages&lt;BR&gt;/// &amp;lt;/summary&amp;gt;&lt;BR&gt;private void ReplyListener(Object state)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Thread.CurrentThread.Name = "LunchManager - Reply Listener";&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Listen&amp;lt;LunchInvitationReply&amp;gt;(this.WaitMilliseconds);&lt;BR&gt;}&lt;/P&gt;
&lt;P&gt;/// &amp;lt;summary&amp;gt;&lt;BR&gt;/// Receive lunch details messages&lt;BR&gt;/// &amp;lt;/summary&amp;gt;&lt;BR&gt;private void LunchDetailsListener(Object state)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Thread.CurrentThread.Name = "LunchManager - Lunch Details Listener";&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Listen&amp;lt;LunchDetails&amp;gt;(this.WaitMilliseconds);&lt;BR&gt;}&lt;BR&gt;&lt;/CODE&gt;&lt;BR&gt;Quite a bit smaller and very similar, aren't they?&amp;nbsp; All of the common listening code, that had been triplicated, has been factored into a generic method called Listen&amp;lt;T&amp;gt;.&amp;nbsp; Let's look at that next.&lt;BR&gt;&lt;CODE&gt;&lt;BR&gt;/// &amp;lt;summary&amp;gt;&lt;BR&gt;/// Receive incoming messages&lt;BR&gt;/// &amp;lt;/summary&amp;gt;&lt;BR&gt;/// &amp;lt;typeparam name="T"&amp;gt;&lt;BR&gt;/// The type of messages that will be received&lt;BR&gt;/// &amp;lt;/typeparam&amp;gt;&lt;BR&gt;/// &amp;lt;param name="waitMilliseconds"&amp;gt;&lt;BR&gt;/// The length of time, in milliseconds, to wait before restarting after a communications failure&lt;BR&gt;/// &amp;lt;/param&amp;gt;&lt;BR&gt;private void Listen&amp;lt;T&amp;gt;(Int32 waitMilliseconds)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; TransportObjects transport = null;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; try&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Type objType = typeof(T);&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // get the transport&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; transport = GetTransport&amp;lt;T&amp;gt;();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; transport.Initialize();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // get the serializer&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; LunchObjectSerializer serializer = GetSerializer&amp;lt;T&amp;gt;();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Boolean keepRunning = true;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; while(keepRunning)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IInputChannel channel = transport.InputChannel;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // wait for a message&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // note: there is no need for a timeout when calling Receive()&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&amp;nbsp; when the channel is closed, Receive() will return&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Message msg = channel.Receive();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(null != msg)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // there is a message to process&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // get the sender's email address&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; String from = (String)msg.Properties["FromEmailAddress"];&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // process the message&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ProcessMessage&amp;lt;T&amp;gt;(msg, from);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // there is no message to process&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // determine why we did not receive a message&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; switch(channel.State)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // transport faulted&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; case CommunicationState.Faulted:&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // attempt to recover from the fault&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; keepRunning = transport.Recover();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // channel is closing/closed&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; case CommunicationState.Closing:&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; case CommunicationState.Closed:&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; keepRunning = false;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // unexpected state&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; default:&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; catch(CommunicationException)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // failure communicating with the service&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&amp;nbsp; sleep for a short time to allow it to recover&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Thread.Sleep(waitMilliseconds);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; catch&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // fatal error&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; keepRunning = false;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; catch(Exception e)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // fatal error&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // TODO: log failure&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; finally&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; transport.Uninitialize();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;}&lt;BR&gt;&lt;/CODE&gt;&lt;BR&gt;The Listen&amp;lt;T&amp;gt; method looks pretty similar to the InvitationListener from the MEDC version.&amp;nbsp; The changes were mostly to make the code reusable, yet still type safe by turning it into a generic method.&amp;nbsp; &lt;BR&gt;&lt;BR&gt;The key change here is to retrieve the appropriate TransportObjects and LunchObjectSerializer from collections managed by the lunch manager (to be talked about in a future post).&amp;nbsp; The rest is mostly just fit-and-finish and "tidying up" (ex: eliminate the TimeoutException that occurred whenever there was no message to receive).&lt;BR&gt;&lt;BR&gt;Since this is an in-progress journey (as noted by the presence of 'TODO' in the snippet), there is still some testing and fine tuning to be done within the Lunch Launcher.&amp;nbsp; As changes are made, I plan on updating this and other posts in the series.&lt;BR&gt;&lt;BR&gt;Upon reflection -- not the .NET type of reflection :) -- I realize that code clarity is not that much different between the MEDC to Oct 2007 versions of the listener.&amp;nbsp; In fact, the Oct 2007 version showcases just how similar the listeners are and might, in fact, be the clearer of the two.&lt;BR&gt;&lt;BR&gt;Take care,&lt;BR&gt;-- DK&lt;BR&gt;&lt;BR&gt;&lt;FONT face=Arial size=1&gt;[Edit: changed titile, we'll talk about processing next time]&lt;BR&gt;&lt;BR&gt;Disclaimer(s):&lt;BR&gt;This posting is provided "AS IS" with no warranties, and confers no rights.&lt;BR&gt;The information contained within this post is in relation to beta software.&amp;nbsp; Any and all details are subject to change.&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5427375" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/davidklinems/archive/tags/Windows+Communication+Foundation/default.aspx">Windows Communication Foundation</category></item><item><title>The Journey of the Lunch Launcher - Part 4b: The output channel</title><link>http://blogs.msdn.com/davidklinems/archive/2007/10/03/the-journey-of-the-lunch-launcher-part-4b-the-output-channel.aspx</link><pubDate>Wed, 03 Oct 2007 20:59:19 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5266135</guid><dc:creator>DavidKlineMS</dc:creator><slash:comments>6</slash:comments><comments>http://blogs.msdn.com/davidklinems/comments/5266135.aspx</comments><wfw:commentRss>http://blogs.msdn.com/davidklinems/commentrss.aspx?PostID=5266135</wfw:commentRss><description>&lt;p&gt;&lt;a href="http://blogs.msdn.com/davidklinems/archive/2007/09/07/the-journey-of-the-lunch-launcher-part-1-the-origins-of-the-lunch-launcher.aspx"&gt;Part 1 - The origins of the 'lunch launcher'&lt;/a&gt;&lt;br&gt;&lt;a href="http://blogs.msdn.com/davidklinems/archive/2007/09/10/the-journey-of-the-lunch-launcher-part-2-medc-2007.aspx"&gt;Part 2 - MEDC 2007&lt;/a&gt;&lt;br&gt;&lt;a href="http://blogs.msdn.com/davidklinems/archive/2007/09/11/the-journey-of-the-lunch-launcher-part-3-managing-the-transport.aspx"&gt;Part 3 - Managing the Transport&lt;/a&gt;&lt;br&gt;&lt;a href="http://blogs.msdn.com/davidklinems/archive/2007/09/28/the-journey-of-the-lunch-launcher-part-4-sending-messages.aspx"&gt;Part 4 - Sending messages&lt;/a&gt;&lt;br&gt;&lt;br&gt;There is a time honored tradition in some television series of having, for example, 'Season 4' and 'Season 4b'.&amp;nbsp; This weblog is no different.&amp;nbsp; Welcome to Part 4b!&lt;br&gt;&lt;br&gt;Last time, I described &lt;a href="http://blogs.msdn.com/davidklinems/archive/2007/09/28/the-journey-of-the-lunch-launcher-part-4-sending-messages.aspx"&gt;how the Lunch Launcher sends messages&lt;/a&gt;.&amp;nbsp; As I was working on the project, I noticed that I had referenced a TransportObjects method that I had not explained in my description: CreateOutputChannel.&lt;br&gt;&lt;br&gt;As with all entries in this series, please note that the following disclaimer covers all examples contained herein.&lt;br&gt;&lt;code&gt;&lt;br&gt;//-----------------------------------------------------------------------&lt;br&gt;//THIS CODE AND INFORMATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY&lt;br&gt;//KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE&lt;br&gt;//IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A&lt;br&gt;//PARTICULAR PURPOSE.&lt;br&gt;//-----------------------------------------------------------------------&lt;br&gt;&lt;br&gt;/// &amp;lt;summary&amp;gt;&lt;br&gt;/// Create an output channel on which messages will be sent&lt;br&gt;/// &amp;lt;/summary&amp;gt;&lt;br&gt;private IOutputChannel CreateOutputChannel(List&amp;lt;String&amp;gt; recipients)&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IOutputChannel outputChannel = null;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // build the recipient endpoint&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Uri uri = MailUriHelper.CreateUri(this.m_ChannelName, &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; recipients.ToArray());&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; EndpointAddress endpoint = new EndpointAddress(uri);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // create the output channel&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; outputChannel = this.OutputChannelFactory.CreateChannel(endpoint);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return outputChannel;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;}&lt;br&gt;&lt;/code&gt;&lt;br&gt;This method uses the MailUriHelper object (part of Store and Forward messaging) to create a single Uri that addresses all recipients.&amp;nbsp; This Uri is then used by the output channel factory to create the channel on which the message will be sent.&lt;br&gt;&lt;br&gt;Take care,&lt;br&gt;-- DK&lt;br&gt;&lt;br&gt;&lt;font face="Arial" size="1"&gt;Disclaimer(s):&lt;br&gt;This posting is provided "AS IS" with no warranties, and confers no rights.&lt;br&gt;The information contained within this post is in relation to beta software.&amp;nbsp; Any and all details are subject to change.&lt;/font&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5266135" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/davidklinems/archive/tags/Windows+Communication+Foundation/default.aspx">Windows Communication Foundation</category></item><item><title>The Journey of the Lunch Launcher: Part 4 - Sending messages</title><link>http://blogs.msdn.com/davidklinems/archive/2007/09/28/the-journey-of-the-lunch-launcher-part-4-sending-messages.aspx</link><pubDate>Sat, 29 Sep 2007 00:52:28 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5192753</guid><dc:creator>DavidKlineMS</dc:creator><slash:comments>9</slash:comments><comments>http://blogs.msdn.com/davidklinems/comments/5192753.aspx</comments><wfw:commentRss>http://blogs.msdn.com/davidklinems/commentrss.aspx?PostID=5192753</wfw:commentRss><description>&lt;p&gt;&lt;a href="http://blogs.msdn.com/davidklinems/archive/2007/09/07/the-journey-of-the-lunch-launcher-part-1-the-origins-of-the-lunch-launcher.aspx"&gt;Part 1 - The origins of the 'lunch launcher'&lt;/a&gt;&lt;br&gt;&lt;a href="http://blogs.msdn.com/davidklinems/archive/2007/09/10/the-journey-of-the-lunch-launcher-part-2-medc-2007.aspx"&gt;Part 2 - MEDC 2007&lt;/a&gt;&lt;br&gt;&lt;a href="http://blogs.msdn.com/davidklinems/archive/2007/09/11/the-journey-of-the-lunch-launcher-part-3-managing-the-transport.aspx"&gt;Part 3 - Managing the Transport&lt;/a&gt;&lt;br&gt;&lt;br&gt;Last time, I talked about how the Lunch Launcher &lt;a href="http://blogs.msdn.com/davidklinems/archive/2007/09/11/the-journey-of-the-lunch-launcher-part-3-managing-the-transport.aspx"&gt;manages the transport objects&lt;/a&gt; used to communicate via Store and Forward Messaging on the .NET Compact Framework.&amp;nbsp; Today, I'm going to discuss how messages are sent.&lt;br&gt;&lt;br&gt;As with all entries in this series, please note that the following disclaimer covers all examples contained herein.&lt;br&gt;&lt;code&gt;&lt;br&gt;//-----------------------------------------------------------------------&lt;br&gt;//THIS CODE AND INFORMATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY&lt;br&gt;//KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE&lt;br&gt;//IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A&lt;br&gt;//PARTICULAR PURPOSE.&lt;br&gt;//-----------------------------------------------------------------------&lt;br&gt;&lt;/code&gt;&lt;br&gt;&lt;strong&gt;MEDC 2007&lt;br&gt;&lt;/strong&gt;When preparing for MEDC 2007, I wrote the code mostly to be functional and illustrative.&amp;nbsp; I was not as concerned about optimizations.&amp;nbsp; The example below comes directly from the MEDC 2007 demo project.&amp;nbsp; In a little bit, we will see how it has changed since then.&amp;nbsp; In both versions of the project, the SendMessage method is a member of the TransportObjects class that I introduced in &lt;a href="http://blogs.msdn.com/davidklinems/archive/2007/09/11/the-journey-of-the-lunch-launcher-part-3-managing-the-transport.aspx"&gt;part 3&lt;/a&gt;.&lt;br&gt;&lt;code&gt;&lt;br&gt;/// &amp;lt;summary&amp;gt;&lt;br&gt;/// Send a message&lt;br&gt;/// &amp;lt;/summary&amp;gt;&lt;br&gt;/// &amp;lt;param name="recipients"&amp;gt;&lt;br&gt;/// Collection of recipient email addresses&lt;br&gt;/// &amp;lt;/param&amp;gt;&lt;br&gt;/// &amp;lt;param name="messageBody"&amp;gt;&lt;br&gt;/// The message contents&lt;br&gt;/// &amp;lt;/param&amp;gt;&lt;br&gt;public void SendMessage(List&amp;lt;String&amp;gt; recipients,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Object messageBody)&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // create the serializer&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; LunchObjectSerializer serializer = &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new LunchObjectSerializer(messageBody.GetType());&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // create the output channel&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IOutputChannel outputChannel = CreateOutputChannel(recipients);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; outputChannel.Open();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // create the message&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Message msg = Message.CreateMessage(&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // use the channel's default version&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; outputChannel.GetProperty&amp;lt;MessageVersion&amp;gt;(),&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "urn:Microsoft.ServiceModel.Samples.LunchLauncher",&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; messageBody,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; serializer);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // send the message&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; outputChannel.Send(msg);&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // close the output channel&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; outputChannel.Close(); &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; outputChannel = null;&amp;nbsp;&amp;nbsp; &lt;br&gt;}&amp;nbsp; &lt;br&gt;&lt;/code&gt;&lt;br&gt;How does it work?&amp;nbsp; SendMessage is called with a collection of email addresses corresponding to the user's buddies (managed by the lunch launcher engine) and the payload for the message.&lt;br&gt;&lt;br&gt;The first thing SendMessage does is to construct a LunchObjectSerializer (an implementation of XmlObjectSerializer) and tells it what type of object it will be serializing (via messageBody.GetType()).&amp;nbsp; Next, SendMessage creates and opens the channel used to send the message to the recipients.&amp;nbsp; &lt;br&gt;&lt;br&gt;Once we have the output channel, the Message object can be created from the message body and serializer.&amp;nbsp; The message is then sent an the output channel is closed (it is no longer needed).&lt;br&gt;&lt;br&gt;That's how &lt;strong&gt;&lt;em&gt;all&lt;/em&gt;&lt;/strong&gt; messages are sent in the Lunch Launcher.&amp;nbsp; There is no custom code for any of the message types.&amp;nbsp; &lt;br&gt;&lt;br&gt;&lt;strong&gt;Current version&lt;/strong&gt;&lt;br&gt;Since coming back to Redmond and spending some time on the Lunch Launcher project, I have made a change to how messages are sent&amp;nbsp; Here's how the SendMessage method looks today.&lt;br&gt;&lt;code&gt;&lt;br&gt;/// &amp;lt;summary&amp;gt;&lt;br&gt;/// Send a message&lt;br&gt;/// &amp;lt;/summary&amp;gt;&lt;br&gt;/// &amp;lt;param name="recipients"&amp;gt;&lt;br&gt;/// Collection of recipient email addresses&lt;br&gt;/// &amp;lt;/param&amp;gt;&lt;br&gt;/// &amp;lt;param name="messageBody"&amp;gt;&lt;br&gt;/// The message contents&lt;br&gt;/// &amp;lt;/param&amp;gt;&lt;br&gt;/// &amp;lt;param name="serializer"&amp;gt;&lt;br&gt;/// The serializer used to encode the message for sending&lt;br&gt;/// &amp;lt;/param&amp;gt;&lt;br&gt;public void SendMessage(List&amp;lt;String&amp;gt; recipients,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Object messageBody,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; LunchObjectSerializer serializer) &lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // create the output channel&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IOutputChannel outputChannel = CreateOutputChannel(recipients);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; outputChannel.Open();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // create the message&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Message msg = Message.CreateMessage(&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // use the channel's default version&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; outputChannel.GetProperty&amp;lt;MessageVersion&amp;gt;(),&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "urn:Microsoft.ServiceModel.Samples.LunchLauncher",&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; messageBody,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; serializer);&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // send the message&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; outputChannel.Send(msg);&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // close the output channel&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; outputChannel.Close(); &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; outputChannel = null;&amp;nbsp;&amp;nbsp; &lt;br&gt;}&amp;nbsp; &lt;br&gt;&lt;/code&gt;&lt;br&gt;Did you spot the change?&amp;nbsp; SendMessage is now called with a third parameter -- the LunchObjectSerializer.&amp;nbsp; The LunchObjectSerializer had previously created within SendMessage.&amp;nbsp; This was done to optimize memory use and performance. &lt;br&gt;&lt;br&gt;Every time an XmlSerializer is created for an object, that object must be examined via Reflection to determine how to convert its contents into XML.&amp;nbsp; As has been discussed on many weblogs and conference presentations, Reflection is expensive.&amp;nbsp; By reducing the number of times the LunchObjectSerializer object is created, the memory footprint is lower and performance improves (less reflection, fewer garbage collections).&amp;nbsp; In fact, I was able to get the number of serializers down to exactly three for the entire application.&amp;nbsp; The same serializers are used for sending and receiving messages.&lt;br&gt;&lt;br&gt;In the MEDC version, there was a performance penalty for being popular (sending more messages).&amp;nbsp; In the current implementation, the popularity penalty has been eliminated. :)&lt;br&gt;&lt;br&gt;Next time, we'll look at how messages are received and processed.&lt;br&gt;&lt;br&gt;Take care,&lt;br&gt;-- DK&lt;br&gt;&lt;br&gt;&lt;font face="Arial" size="1"&gt;Disclaimer(s):&lt;br&gt;This posting is provided "AS IS" with no warranties, and confers no rights.&lt;br&gt;The information contained within this post is in relation to beta software.&amp;nbsp; Any and all details are subject to change.&lt;/font&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5192753" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/davidklinems/archive/tags/Windows+Communication+Foundation/default.aspx">Windows Communication Foundation</category></item><item><title>The Journey of the Lunch Launcher: Part 3 - Managing the Transport</title><link>http://blogs.msdn.com/davidklinems/archive/2007/09/11/the-journey-of-the-lunch-launcher-part-3-managing-the-transport.aspx</link><pubDate>Wed, 12 Sep 2007 01:04:19 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4871050</guid><dc:creator>DavidKlineMS</dc:creator><slash:comments>12</slash:comments><comments>http://blogs.msdn.com/davidklinems/comments/4871050.aspx</comments><wfw:commentRss>http://blogs.msdn.com/davidklinems/commentrss.aspx?PostID=4871050</wfw:commentRss><description>&lt;p&gt;&lt;a href="http://blogs.msdn.com/davidklinems/archive/2007/09/07/the-journey-of-the-lunch-launcher-part-1-the-origins-of-the-lunch-launcher.aspx"&gt;Part 1 - The origins of the 'lunch launcher'&lt;/a&gt;&lt;br&gt;&lt;a href="http://blogs.msdn.com/davidklinems/archive/2007/09/10/the-journey-of-the-lunch-launcher-part-2-medc-2007.aspx"&gt;Part 2 - MEDC 2007&lt;/a&gt;&lt;br&gt;&lt;br&gt;In the first two installments (linked above), I introduced the lunch launcher and talked about getting ready for its debut at MEDC 2007 in Las Vegas.&amp;nbsp; Now it's time to start looking at how the .NET Compact Framework&amp;nbsp; v3.5 Store and Forward Messaging feature makes this application possible.&lt;br&gt;&lt;br&gt;At the heart of the lunch launcher are the Windows Communication Foundation channel pairs (input and output).&amp;nbsp; You may ask 'what do you mean channel pairs, isn't the one channel that sends and receives'?&amp;nbsp; Excellent question!&amp;nbsp; The answer is no.&amp;nbsp; The Store and Forward Messaging feature is built upon one-way communications channels (IInputChannel and IOutputChannel).&amp;nbsp; This is necessary due to the nature of email as a transport.&amp;nbsp; Email has, what I term, variable latency.&amp;nbsp; By variable latency, I mean that once a message has been sent, the time it will take for it to be received cannot be determined.&amp;nbsp; It may be received in a few seconds, a few hours, a few days or never depending on when and if the recipient checks their email.&amp;nbsp; This leads to some very interesting challenges in writing applications which leverage Store and Forward Messaging.&amp;nbsp; I plan on discussing these challenges in a future post (separate from this series).&lt;br&gt;&lt;br&gt;Back to the topic at hand... How does the lunch launcher manage the transport?&amp;nbsp; All objects required to send and receive messages, for all three of the lunch launcher channel pairs (invitations, replies and notifications) are contained in a TransportObjects class, as shown below.&amp;nbsp; This example is taken directly from the MEDC 2007 demo project. &lt;br&gt;&lt;br&gt;Please note that specific details of property implementation and object construction have been removed for space reasons and that the following disclaimer covers all examples contained herein.&lt;br&gt;&lt;code&gt;&lt;br&gt;//-----------------------------------------------------------------------&lt;br&gt;//THIS CODE AND INFORMATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY&lt;br&gt;//KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE&lt;br&gt;//IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A&lt;br&gt;//PARTICULAR PURPOSE.&lt;br&gt;//-----------------------------------------------------------------------&lt;br&gt;&lt;br&gt;/// &amp;lt;summary&amp;gt;&lt;br&gt;/// Object to encapsulate and simplify working with &lt;br&gt;/// Windows Communication Framework objects&lt;br&gt;/// &amp;lt;/summary&amp;gt;&lt;br&gt;public class TransportObjects&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// The binding used to create the channels&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public WindowsMobileMailBinding Binding&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { get; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// The name of the input channel (ex: "MyServiceChannel")&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public String ChannelName&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { get; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// The input channel&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public IInputChannel InputChannel&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { get; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// The channel factory used to create output channels&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public IChannelFactory&amp;lt;IOutputChannel&amp;gt; OutputChannelFactory&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { get; }&lt;br&gt;}&lt;br&gt;&lt;/code&gt;&lt;br&gt;The application engine creates the TransportObjects object and then initialize them (create the necessary Windows Communication Foundation objects) by calling Initialize().&lt;br&gt;&lt;code&gt;&lt;br&gt;/// &amp;lt;summary&amp;gt;&lt;br&gt;/// Initializes the Windows Communication Foundation objects&lt;br&gt;/// &amp;lt;/summary&amp;gt;&lt;br&gt;public void Initialize()&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; try&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.m_Binding = new WindowsMobileMailBinding();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.m_Binding.AcceptExistingMessages = true;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // create the binding parameters used by our channels&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; BindingParameterCollection bpc = new BindingParameterCollection();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // NOTE: input channel gets the email address from the binding&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Uri inputChannelUri = MailUriHelper.CreateUri(this.m_ChannelName, "");&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // create the input channel listener&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IChannelListener&amp;lt;IInputChannel&amp;gt; listener = &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.m_Binding.BuildChannelListener&amp;lt;IInputChannel&amp;gt;(inputChannelUri, bpc);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; listener.Open();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // create the input channel&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.m_InputChannel = listener.AcceptChannel();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.m_InputChannel.Open();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // now that we have the input channel, &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&amp;nbsp; it is safe to close the listener&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; listener.Close();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; listener = null;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // create the output channel factory&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.m_OutputChannelFactory = this.m_Binding.BuildChannelFactory&amp;lt;IOutputChannel&amp;gt;(bpc);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.m_OutputChannelFactory.Open();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; catch&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // initialization failed, make sure we cleanup&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Uninitialize();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; throw;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;}&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/code&gt;&lt;br&gt;When the application engine is done with a channel pair (at shutdown) or if anything bad occurs (exception on initialization, for example) Uninitialize() is called.&lt;br&gt;&lt;code&gt;&lt;br&gt;/// &amp;lt;summary&amp;gt;&lt;br&gt;/// Uninitializes and cleans up the Windows Communication Foundation objects&lt;br&gt;/// &amp;lt;/summary&amp;gt;&lt;br&gt;public void Uninitialize()&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(null != this.m_InputChannel)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.m_InputChannel.Close();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.m_InputChannel = null;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(null != this.m_OutputChannelFactory)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.m_OutputChannelFactory.Close();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.m_OutputChannelFactory = null;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(null != this.m_Binding)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.m_Binding.Close();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.m_Binding = null;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;}&lt;br&gt;&lt;/code&gt;&lt;br&gt;In the event that the application engine encounters a faulted state on the transport, recovery is performed by the Recover() method.&amp;nbsp; Recover calls Uninitialize and Initialize.&amp;nbsp; If both succeed, success is indicated by the method returning true.&amp;nbsp; Upon a true return, the application logic continues to send and receive messages.&amp;nbsp; A false return aborts the channel pair's functionality.&lt;br&gt;&lt;code&gt;&lt;br&gt;/// &amp;lt;summary&amp;gt;&lt;br&gt;/// Recovers from a transport fault by uninitializing and reinitializing&lt;br&gt;/// the Windows Communication Foundation objects&lt;br&gt;/// &amp;lt;/summary&amp;gt;&lt;br&gt;/// &amp;lt;returns&amp;gt;&lt;br&gt;/// True if recovery was successful, false otherwise&lt;br&gt;/// &amp;lt;/returns&amp;gt;&lt;br&gt;public Boolean Recover()&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Boolean recovered;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; try&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Uninitialize();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Initialize();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // successful recovery&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; recovered = true;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; catch&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // unsuccessful recovery&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; recovered = false;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Uninitialize();&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return recovered;&lt;br&gt;}&lt;br&gt;&lt;/code&gt;&lt;br&gt;Take care,&lt;br&gt;-- DK&lt;br&gt;&lt;br&gt;&lt;font face="Arial" size="1"&gt;Disclaimer(s):&lt;br&gt;This posting is provided "AS IS" with no warranties, and confers no rights.&lt;br&gt;The information contained within this post is in relation to beta software.&amp;nbsp; Any and all details are subject to change.&lt;/font&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=4871050" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/davidklinems/archive/tags/Windows+Communication+Foundation/default.aspx">Windows Communication Foundation</category></item><item><title>The Journey of the Lunch Launcher: Part 2 - MEDC 2007</title><link>http://blogs.msdn.com/davidklinems/archive/2007/09/10/the-journey-of-the-lunch-launcher-part-2-medc-2007.aspx</link><pubDate>Tue, 11 Sep 2007 02:01:43 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4857477</guid><dc:creator>DavidKlineMS</dc:creator><slash:comments>14</slash:comments><comments>http://blogs.msdn.com/davidklinems/comments/4857477.aspx</comments><wfw:commentRss>http://blogs.msdn.com/davidklinems/commentrss.aspx?PostID=4857477</wfw:commentRss><description>&lt;p&gt;In &lt;a href="http://blogs.msdn.com/davidklinems/archive/2007/09/07/the-journey-of-the-lunch-launcher-part-1-the-origins-of-the-lunch-launcher.aspx"&gt;part 1&lt;/a&gt;, I introduced the lunch launcher.&amp;nbsp; Today, I'm going to talk a bit about the preparations for the "world premier" of the lunch launcher from MEDC 2007.&lt;br&gt;&lt;br&gt;Before getting started, I set out a few goals:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Provide an introduction to the Store and Forward Messaging feature of .NET Compact Framework v3.5&lt;/li&gt; &lt;li&gt;Demonstrate point-to-point device communications via Store and Forward Messaging&lt;/li&gt; &lt;li&gt;Implement invite / reply functionality (voting and destination notification were not a goal for the demo)&lt;/li&gt; &lt;li&gt;Minimize duplicate communications code where possible&lt;/li&gt; &lt;li&gt;Use additional .NET Compact Framework v3.5 new features as appropriate and/or interesting&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;With the goals defined, I sat down to write my vision of the lunch launcher.&amp;nbsp; I installed an almost beta 1 release of Visual Studio 2008 (then node named 'Orcas') and created a Windows Mobile 6 Professional project.&lt;br&gt;&lt;br&gt;The first thing I wanted to be sure to do was to reinforce some of what I would be talking about in my &lt;a href="http://blogs.msdn.com/davidklinems/archive/2007/01/26/medc-2007-real-world-testing-of-managed-smart-device-applications.aspx"&gt;Thursday session&lt;/a&gt; -- GUI-Logic separation.&amp;nbsp; While not split into separate assemblies for MEDC (they are split now) the user interface and business logic (aka the engine) were contained in a collection of classes across two namespaces.&amp;nbsp; &lt;br&gt;&lt;br&gt;My next goal was to design the communications to be as simple, and re-usable as possible.&amp;nbsp; Though I did not completely achieve this in the MEDC demo, it has since been accomplished.&amp;nbsp; I will talk about the changes between the MEDC and current designs in a later installment.&amp;nbsp; &lt;br&gt;&lt;br&gt;The communications required by the lunch launcher fall into three transactions: invitations, invitation replies and destination (where to meet for lunch) notifications.&amp;nbsp; I implemented separate channel pairs (send and receive) for each transaction.&amp;nbsp; By designing this way, each input channel knows how to receive exactly one message type, no complex "what type of message did I receive" logic.&amp;nbsp; Similarly, output channels need only know how to send a single message type.&lt;br&gt;&lt;br&gt;For the sending of the messages, I discovered that the code was nearly identical for all three of my transactions.&amp;nbsp; The only differences were the message type and the name of the channel that would be receiving the message.&amp;nbsp; This got me thinking about encapsulation.&amp;nbsp; As a result, I created an object that contained all of the required Windows Communication Foundation objects and a method to send the message.&amp;nbsp; This was very effective and allowed me to fix issues in all three channel pairs with one code change.&lt;br&gt;&lt;br&gt;For the receiving of messages, I actually had three copies of very similar code.&amp;nbsp; Since this was an introductory demonstration, I elected to not factor the common code until after MEDC.&amp;nbsp; Instead, I used the duplicated code to illustrate how similar the transactions actually were. &lt;br&gt;&lt;br&gt;Remember when I said I installed an "almost beta 1" release?&amp;nbsp; I went into panic mode when I installed the final beta 1 build and found that I could not build my application (see &lt;a href="http://blogs.msdn.com/markprenticems"&gt;Mark&lt;/a&gt;'s &lt;a href="http://blogs.msdn.com/markprenticems/archive/2007/05/29/store-and-forward-channel-beta1-take-two.aspx"&gt;post&lt;/a&gt; for the why's).&amp;nbsp; The issue identified (and worked around for the trip), I went back to fine tuning the demo.&lt;br&gt;&lt;br&gt;&lt;strong&gt;Tuesday morning, Las Vegas:&lt;/strong&gt;&amp;nbsp; In the final morning session of the first day of MEDC, I took the stage in what&amp;nbsp; I called "the big room" (as opposed to the "really big room" where the keynote was held) to present in front of my largest audience to date.&amp;nbsp; The room held about 400 people and I was told that there was standing in the aisles and in the hall (wow!).&lt;br&gt;&lt;br&gt;When it came time to unveil the lunch launcher, I wondered (not for the first time) if I had too much coffee as my nerves were on high alert.&amp;nbsp; Demonstrating pre-release software live on stage is a scary thing.&amp;nbsp; Any of a number of little things could easily go wrong.&amp;nbsp; Fortunately for me, things went extremely well.&amp;nbsp; Even the delays waiting for message delivery through the server were minimal -- so minimal, in fact, that I was still explaining what was occurring when the messages arrived.&lt;br&gt;&lt;br&gt;The lunch launcher was now officially real.&amp;nbsp; :)&lt;br&gt;&lt;br&gt;With a successful demonstration of peer-to-peer social messaging complete, it was time to show how it worked.&amp;nbsp; Since this post has gotten a little long winded, I will save that discussion for the next installment.&lt;br&gt;&lt;br&gt;Take care!&lt;br&gt;-- DK&lt;br&gt;&lt;br&gt;&lt;font face="Arial" size="1"&gt;Disclaimer(s):&lt;br&gt;This posting is provided "AS IS" with no warranties, and confers no rights.&lt;br&gt;The information contained within this post is in relation to beta software.&amp;nbsp; Any and all details are subject to change.&lt;/font&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=4857477" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/davidklinems/archive/tags/Windows+Communication+Foundation/default.aspx">Windows Communication Foundation</category></item><item><title>The Journey of the Lunch Launcher: Part 1 - The origins of the 'lunch launcher'?</title><link>http://blogs.msdn.com/davidklinems/archive/2007/09/07/the-journey-of-the-lunch-launcher-part-1-the-origins-of-the-lunch-launcher.aspx</link><pubDate>Sat, 08 Sep 2007 01:44:55 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4817860</guid><dc:creator>DavidKlineMS</dc:creator><slash:comments>17</slash:comments><comments>http://blogs.msdn.com/davidklinems/comments/4817860.aspx</comments><wfw:commentRss>http://blogs.msdn.com/davidklinems/commentrss.aspx?PostID=4817860</wfw:commentRss><description>&lt;p&gt;Several years ago, when I first joined the .NET Compact Framework team, we took some time (a week, if memory serves) to play with our product.&amp;nbsp; We called that our "app building" time.&amp;nbsp; At it's heart, app building is an opportunity for us to get a feel for the experience our customers will have with our product.&amp;nbsp; Whenever app building time is scheduled, I'm like a kid in a candy store. :)&lt;br&gt;&lt;br&gt;During that first app building week, many of us got together to brainstorm cool applications.&amp;nbsp; One of these we called the "lunch launcher".&amp;nbsp; In a nutshell, the lunch launcher would be a social application that allowed friends to invite each other to lunch at a specific time and collect votes for the desired restaurant.&amp;nbsp; Shortly before the scheduled time to eat, a notification would be sent to everyone with the selected restaurant.&lt;br&gt;&lt;br&gt;Unfortunately, the lunch launcher was an application whose time had not yet come.&amp;nbsp; It was not technically feasible to write a networked application that communicated point-to-point with other devices to schedule lunch, so we shelved the idea.&lt;br&gt;&lt;br&gt;Shelved, that is, until we started planning .NET Compact Framework version 3.5...&amp;nbsp; enter the Windows Communication Foundation.&lt;br&gt;&lt;br&gt;About two years ago, &lt;a href="http://blogs.msdn.com/romanbat"&gt;Roman Batoukov&lt;/a&gt; wrote a post titled "&lt;a href="http://blogs.msdn.com/romanbat/archive/2006/10/21/windows-communication-foundation-compact-edition-and-the-story-of-the-lunch-launcher.aspx"&gt;Windows Communication Foundation (Compact Edition) and the story of the Lunch Launcher&lt;/a&gt;".&amp;nbsp; As Roman (and later, &lt;a href="http://blogs.msdn.com/markprenticems/archive/2007/04/25/introduction-to-the-windows-communication-foundation-for-the-net-compact-framework-store-and-forward-messaging.aspx"&gt;Mark Prentice&lt;/a&gt;) described, version 3.5 adds a subset of the Windows Communication Foundation that was released as part of version 3.0 of the .NET Framework.&amp;nbsp; While planning the Windows Communication Foundation subset, an epiphany occurred.&amp;nbsp;&amp;nbsp;&amp;nbsp; Why not implement a Windows Communication Foundation channel that uses email as the transport?&amp;nbsp; Using email for communications would provide a number of big benefits, most specifically a means for addressing the device, regardless of which network it is currently on, and a way to store messages for later transmission if the device is offline at the time of the send.&amp;nbsp; &lt;br&gt;&lt;br&gt;As a member of the Windows Communication Foundation feature team, I started thinking about the lunch launcher again.&amp;nbsp; When we were preparing for &lt;a href="http://blogs.msdn.com/davidklinems/archive/2007/03/01/medc-2007-what-s-new-in-net-compact-framework-v3-5.aspx"&gt;MEDC 2007&lt;/a&gt;, I had the privilege of writing and debuting the concept in front of more than 400 attendees and talking about it one-on-one with many throughout conference.&amp;nbsp; The lunch launcher was finally alive!&lt;br&gt;&lt;br&gt;For the remainder of this series, I will be talking about my journey of writing the lunch launcher (one that I am still embarked on).&amp;nbsp; I will start with the original MEDC 2007 demo application and go through the evolution of the application wanted to write when we first dreamt of the lunch launcher.&amp;nbsp; I hope you will find my tale interesting and informative.&lt;br&gt;&lt;br&gt;Take care!&lt;br&gt;-- DK&lt;br&gt;&lt;br&gt;&lt;font face="Arial" size="1"&gt;Disclaimer(s):&lt;br&gt;This posting is provided "AS IS" with no warranties, and confers no rights.&lt;br&gt;The information contained within this post is in relation to beta software.&amp;nbsp; Any and all details are subject to change.&lt;/font&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=4817860" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/davidklinems/archive/tags/Windows+Communication+Foundation/default.aspx">Windows Communication Foundation</category></item><item><title>Handy "What is supported" table for Windows Communication Foundation in .NET Compact Framework v3.5</title><link>http://blogs.msdn.com/davidklinems/archive/2007/09/07/handy-what-is-supported-table-for-windows-communication-foundation-in-net-compact-framework-v3-5.aspx</link><pubDate>Sat, 08 Sep 2007 00:30:09 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4816776</guid><dc:creator>DavidKlineMS</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/davidklinems/comments/4816776.aspx</comments><wfw:commentRss>http://blogs.msdn.com/davidklinems/commentrss.aspx?PostID=4816776</wfw:commentRss><description>&lt;p&gt;Last month, &lt;a href="http://blogs.msdn.com/andrewarnottms"&gt;Andrew Arnott&lt;/a&gt; posted a very handy table &lt;a href="http://blogs.msdn.com/andrewarnottms/archive/2007/08/21/The-WCF-subset-supported-by-NetCF.aspx"&gt;that compares the Windows Communication Foundation features found in .NET Framework v3.0 with those found in .NET Compact Framework v3.5&lt;/a&gt;.&amp;nbsp; This is an invaluable resource for anyone writing Windows Communication Foundation code for both PC and Mobile devices.&lt;br&gt;&lt;br&gt;Take care,&lt;br&gt;-- DK&lt;br&gt;&lt;br&gt;&lt;font face="Arial" size="1"&gt;Disclaimer(s):&lt;br&gt;This posting is provided "AS IS" with no warranties, and confers no rights.&lt;br&gt;The information contained within this post is in relation to beta software.&amp;nbsp; Any and all details are subject to change.&lt;/font&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=4816776" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/davidklinems/archive/tags/Windows+Communication+Foundation/default.aspx">Windows Communication Foundation</category></item><item><title>Mark Prentice Introduces Store and Forward Messaging in .NET Compact Framework v3.5</title><link>http://blogs.msdn.com/davidklinems/archive/2007/04/26/mark-prentice-introduces-store-and-forward-messaging-in-net-compact-framework-v3-5.aspx</link><pubDate>Thu, 26 Apr 2007 21:11:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:2288874</guid><dc:creator>DavidKlineMS</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/davidklinems/comments/2288874.aspx</comments><wfw:commentRss>http://blogs.msdn.com/davidklinems/commentrss.aspx?PostID=2288874</wfw:commentRss><description>&lt;P&gt;Yesterday, &lt;A href="http://blogs.msdn.com/markprenticems" mce_href="http://blogs.msdn.com/markprenticems"&gt;Mark&lt;/A&gt; posted a &lt;A href="http://blogs.msdn.com/markprenticems/archive/2007/04/25/introduction-to-the-windows-communication-foundation-for-the-net-compact-framework-store-and-forward-messaging.aspx" mce_href="http://blogs.msdn.com/markprenticems/archive/2007/04/25/introduction-to-the-windows-communication-foundation-for-the-net-compact-framework-store-and-forward-messaging.aspx"&gt;'Hello World' example using the Store and Forward Messaging technology&lt;/A&gt; which will ship with version 3.5&amp;nbsp;of the .NET Compact Framework (currently in beta).&amp;nbsp;&lt;BR&gt;&lt;BR&gt;For me, this post is particularly exciting since it allows me to start talking about the feature that I have been busilly working on for the past several months - Store and Forward Messaging.&lt;BR&gt;&lt;BR&gt;As&amp;nbsp;Mark mentions in his post, Store and Forward&amp;nbsp;Messaging is built on the &lt;A href="http://msdn2.microsoft.com/en-us/library/ms735119.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/ms735119.aspx"&gt;Windows Communication Foundation&lt;/A&gt; and uses our new Email transport to enable devices to communicate with PC / Server systems as well as other devices.&amp;nbsp; For me, the coolest aspects of Store and Forward Messaging are that it makes devices addressable and I no longer need to worry about whether or not I have connectivity when I send or receive a message -- the email infrastructure takes care of that for me automatically.&lt;BR&gt;&lt;BR&gt;If you are coming to &lt;A href="http://www.medc2007.com/" mce_href="http://www.medc2007.com/"&gt;MEDC 2007&lt;/A&gt;&amp;nbsp;next week, I highly encourage you to attend Mark and Sergey's session (APP325) on Tuesday afternoon.&amp;nbsp; They will be introducing Windows Communication Foundation for the .NET Compact Framework and Store and Forward Messaging.&amp;nbsp; If you would like to give Store and Forward Messaging a test drive while you are there, &lt;A href="http://blogs.msdn.com/anthonywong" mce_href="http://blogs.msdn.com/anthonywong"&gt;Anthony&lt;/A&gt; will be presenting an Instructor-Lead Lab (ILL317) on Tuesday (right before Mark and Sergey's session).&lt;BR&gt;&lt;BR&gt;And, I would be remiss if I neglected to mention &lt;A href="http://blogs.msdn.com/davidklinems/archive/2007/03/01/medc-2007-what-s-new-in-net-compact-framework-v3-5.aspx" mce_href="http://blogs.msdn.com/davidklinems/archive/2007/03/01/medc-2007-what-s-new-in-net-compact-framework-v3-5.aspx"&gt;my own session&lt;/A&gt; during which I will introduce .NET Compact Framework version 3.5 and demonstrate the cool new features we will be delivering with Visual Studio 'Orcas' including Store and Forward Messaging.&lt;BR&gt;&lt;BR&gt;Last October, &lt;A href="http://blogs.msdn.com/romanbat" mce_href="http://blogs.msdn.com/romanbat"&gt;Roman&lt;/A&gt; wrote about the &lt;A href="http://blogs.msdn.com/romanbat/archive/2006/10/21/windows-communication-foundation-compact-edition-and-the-story-of-the-lunch-launcher.aspx" mce_href="http://blogs.msdn.com/romanbat/archive/2006/10/21/windows-communication-foundation-compact-edition-and-the-story-of-the-lunch-launcher.aspx"&gt;Windows Communication Foundation and an application that he called the "Lunch Launcher"&lt;/A&gt;.&amp;nbsp; Back in the early days of the .NET Compact Framework, I was one of the folks who was trying to implement a Lunch Launcher (I owned networking and web services testing back then).&amp;nbsp; This coming Tuesday, during my session (APP214), I will at long last be demonstrating a Lunch Launcher built on Store and Forward Messaging!&amp;nbsp; I cannot wait to finally get to show it to you.&lt;BR&gt;&lt;BR&gt;Take care and hope to see you all at &lt;A href="http://www.medc2007.com/" mce_href="http://www.medc2007.com/"&gt;MEDC&lt;/A&gt;!&lt;BR&gt;--- DK&lt;BR&gt;&lt;BR&gt;&lt;FONT face=Arial size=1&gt;Disclaimers:&lt;BR&gt;This posting is provided "AS IS" with no warranties, and confers no rights.&lt;BR&gt;The information contained within this post is in relation to beta software.&amp;nbsp; Any and all details are subject to change.&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2288874" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/davidklinems/archive/tags/Events/default.aspx">Events</category><category domain="http://blogs.msdn.com/davidklinems/archive/tags/Windows+Communication+Foundation/default.aspx">Windows Communication Foundation</category></item><item><title>Windows Communication Foundation for .NET Compact Framework</title><link>http://blogs.msdn.com/davidklinems/archive/2007/03/27/windows-communication-foundation-for-net-compact-framework.aspx</link><pubDate>Tue, 27 Mar 2007 21:27:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1966496</guid><dc:creator>DavidKlineMS</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/davidklinems/comments/1966496.aspx</comments><wfw:commentRss>http://blogs.msdn.com/davidklinems/commentrss.aspx?PostID=1966496</wfw:commentRss><description>&lt;P&gt;Yesterday, &lt;A href="http://blogs.msdn.com/markprenticems" mce_href="http://blogs.msdn.com/markprenticems"&gt;Mark Prentice&lt;/A&gt; posted an introduction &lt;A href="http://blogs.msdn.com/markprenticems/archive/2007/03/27/introduction-to-windows-communication-foundation-for-the-net-compact-framework-messaging-stack.aspx" mce_href="http://blogs.msdn.com/markprenticems/archive/2007/03/27/introduction-to-windows-communication-foundation-for-the-net-compact-framework-messaging-stack.aspx"&gt;to the Windows Communication Foundation for .NET Compact Framework&lt;/A&gt;.&amp;nbsp; Like him, I would like to recommend reading &lt;A href="http://blogs.msdn.com/romanbat" mce_href="http://blogs.msdn.com/romanbat"&gt;Roman Batoukov&lt;/A&gt;'s &lt;A href="http://blogs.msdn.com/romanbat/archive/2006/10/21/windows-communication-foundation-compact-edition-and-the-story-of-the-lunch-launcher.aspx" mce_href="http://blogs.msdn.com/romanbat/archive/2006/10/21/windows-communication-foundation-compact-edition-and-the-story-of-the-lunch-launcher.aspx"&gt;post from last October&lt;/A&gt;.&lt;BR&gt;&lt;BR&gt;One of the reasons that&amp;nbsp;I have been slow to post to this weblog in recent months is that I have been busy working with Mark and others to deliver the Windows Communication Foundation for .NET Compact Framework.&lt;BR&gt;&lt;BR&gt;I will be posting more on this cool new feature after beta 1 of Visual Studio, code name 'Orcas' has been released and you can take it for a test drive.&lt;BR&gt;&lt;BR&gt;If you are planning on attending &lt;A class="" href="http://www.medc2007.com/" mce_href="http://www.medc2007.com"&gt;MEDC 2007&lt;/A&gt; in Las Vegas (May 1 - 3), I highly recommend Mark and Sergey Kuryata's session on the Windows Communication Foundation.&amp;nbsp; They have some great information and demos planned.&lt;BR&gt;&lt;BR&gt;Take care,&lt;BR&gt;-- DK&lt;BR&gt;&lt;BR&gt;&lt;FONT face=Arial size=1&gt;[Edit: add link to&amp;nbsp;MEDC&amp;nbsp;site]&lt;BR&gt;&amp;nbsp;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face=Arial size=1&gt;Disclaimers:&lt;BR&gt;This posting is provided "AS IS" with no warranties, and confers no rights.&lt;BR&gt;The information contained within this post is in relation to beta software.&amp;nbsp; Any and all details are subject to change.&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1966496" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/davidklinems/archive/tags/Windows+Communication+Foundation/default.aspx">Windows Communication Foundation</category></item></channel></rss>