<?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>Life inside Microsoft Robotics</title><link>http://blogs.msdn.com/pollrobots/default.aspx</link><description /><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>CCR Utilities Part 1</title><link>http://blogs.msdn.com/pollrobots/archive/2008/07/22/ccr-utilities-part-1.aspx</link><pubDate>Wed, 23 Jul 2008 09:48:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8766074</guid><dc:creator>PollRobots</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/pollrobots/comments/8766074.aspx</comments><wfw:commentRss>http://blogs.msdn.com/pollrobots/commentrss.aspx?PostID=8766074</wfw:commentRss><description>
&lt;STYLE type=text/css&gt;
        span.code
        {
            font-family: Consolas, Courier, Monospace;
            font-size: 11px;
            color: #000000;
            background-color: #FFFFFF;
        }
        pre.code
        {
            font-family: Consolas, Courier, Monospace;
            font-size: 11px;
            color: #000000;
            background-color: #FFFFFF;
        }
        span.kwrd
        {
            color: #0000FF;
        }
        span.type
        {
            color: #008080;
        }
        span.str
        {
            color: #800000;
        }
        span.cmt
        {
            color: #008000;
        }
        span.dcmt
        {
            color: #404040;
        }
        span.line
        {
            color: #008080;
            border-right: solid 1 #CCC;
        }
    &lt;/STYLE&gt;

&lt;P&gt;Something that has cropped up a few times — certainly enough times for me to want to do something about it — is the lack of some basic utilities in CCR, not things that necessarily need to find their way into the CCR package, but more some small utility classes that should be in any CCR developers back pocket when they need them.&lt;/P&gt;
&lt;P&gt;The first one that I will address is logging. A number of times I've been shown some code and asked "why is my code not as fast as I would like?", and the core algorithm and implementation is just fine, but scattered around the code are lines like…&lt;/P&gt;&lt;PRE class=code&gt;Log(&lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt;.Format(&lt;SPAN class=str&gt;"{0}: {1}: Starting New Task"&lt;/SPAN&gt;, &lt;SPAN class=type&gt;Thread&lt;/SPAN&gt;.CurrentThread.
    ManagedThreadId, &lt;SPAN class=type&gt;DateTime&lt;/SPAN&gt;.UtcNow));
&lt;/PRE&gt;
&lt;P&gt;Which is entirely reasonable, a little investigation into the implementation of Log can shows the real problem&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN class=kwrd&gt;static&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;object&lt;/SPAN&gt; _logLock = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;object&lt;/SPAN&gt;();

&lt;SPAN class=kwrd&gt;static&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; Log(&lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt; msg)
{
    &lt;SPAN class=kwrd&gt;lock&lt;/SPAN&gt;(_logLock)
    {
        &lt;SPAN class=kwrd&gt;using&lt;/SPAN&gt; (&lt;SPAN class=kwrd&gt;var&lt;/SPAN&gt; stream = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; &lt;SPAN class=type&gt;StreamWriter&lt;/SPAN&gt;(&lt;SPAN class=str&gt;"log.txt"&lt;/SPAN&gt;, &lt;SPAN class=kwrd&gt;true&lt;/SPAN&gt;))
        {
            stream.WriteLine(msg);
        }
    }
}
&lt;/PRE&gt;
&lt;P&gt;There are two big problems here, and they go hand in hand, one is opening and closing a file everytime a message needs to be logged, and the second, probably introduced by the first decision is to call lock. This of course, ensures that the access to the file is safe, but at the cost of introducing lock contention. Potentially every thread in the dispatcher can be stuck in the one place.&lt;/P&gt;
&lt;P&gt;Sometimes on the robotics team we don't realise that this is an issue, in DSS if you want to log there are convenient helper functions on the DsspServiceBase, we forget that CCR doesn't have these.&lt;/P&gt;
&lt;P&gt;But CCR is all about solving this problem! A very simple class can encapsulate most basic logging requirements. All we need to do is post messages to a port, and have write them out in an exclusive handler…&lt;/P&gt;
&lt;P&gt;We start by creating a small CCR service. This is a common CCR pattern where a class is created to perform some task, but its creator uses a factory function (a static public method commonly called Create) which returns the PortSet that it can communicate with the service on, rather than a classic reference to the class.&lt;/P&gt;
&lt;H2&gt;The Service&lt;/H2&gt;&lt;PRE class=code&gt;&lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;sealed&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;class&lt;/SPAN&gt; StreamLogger : &lt;SPAN class=type&gt;CcrServiceBase&lt;/SPAN&gt;
{
    StreamLoggerOperations _port = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; StreamLoggerOperations();
    &lt;SPAN class=type&gt;Port&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=type&gt;EmptyValue&lt;/SPAN&gt;&amp;gt; _tokenPort = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; &lt;SPAN class=type&gt;Port&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=type&gt;EmptyValue&lt;/SPAN&gt;&amp;gt;();
    &lt;SPAN class=type&gt;StreamWriter&lt;/SPAN&gt; _writer;

    &lt;SPAN class=kwrd&gt;private&lt;/SPAN&gt; StreamLogger(&lt;SPAN class=type&gt;StreamWriter&lt;/SPAN&gt; writer, &lt;SPAN class=type&gt;DispatcherQueue&lt;/SPAN&gt; taskQueue)
        : &lt;SPAN class=kwrd&gt;base&lt;/SPAN&gt;(taskQueue)
    {
        _writer = writer;
    }
&lt;/PRE&gt;
&lt;P&gt;In this case the Create method takes the StreamWriter on which logging is to occur, and a DispatcherQueue to use for its own arbiters. Create returns a StreamLoggerOperations object, which we'll look at below&lt;/P&gt;&lt;PRE class=code&gt;    &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;static&lt;/SPAN&gt; StreamLoggerOperations Create(&lt;SPAN class=type&gt;StreamWriter&lt;/SPAN&gt; writer, 
    &lt;SPAN class=type&gt;DispatcherQueue&lt;/SPAN&gt; taskQueue)
    {
        &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (writer == &lt;SPAN class=kwrd&gt;null&lt;/SPAN&gt;)
        {
            &lt;SPAN class=kwrd&gt;throw&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; &lt;SPAN class=type&gt;ArgumentNullException&lt;/SPAN&gt;(&lt;SPAN class=str&gt;"writer"&lt;/SPAN&gt;);
        }
        &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (taskQueue == &lt;SPAN class=kwrd&gt;null&lt;/SPAN&gt;)
        {
            &lt;SPAN class=kwrd&gt;throw&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; &lt;SPAN class=type&gt;ArgumentNullException&lt;/SPAN&gt;(&lt;SPAN class=str&gt;"taskQueue"&lt;/SPAN&gt;);
        }

        &lt;SPAN class=kwrd&gt;var&lt;/SPAN&gt; logger = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; StreamLogger(writer, taskQueue);

        logger.Init();

        &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; logger._port;
    }
&lt;/PRE&gt;
&lt;P&gt;Initialization shows us the only "trick" to this. I could have used an Interleave, and defined one Receiver in the Teardown group (for shutdown) and one Receiver in the Exclusive group (for logging messages). That's a great approach, but here I'm doing something a little different which will give me a slightly more explicit behavior on shutdown.&lt;/P&gt;
&lt;P&gt;You may have noticed above that one of the private fields of the service as _tokenPort, what I am doing is creating a Join over that token port and the string port within the main operations portset. This allows me (by being careful to ensure that only one message is on the token port at a time) to control the way in which string messages posted to the operations port are handled. Each time a the Join fires (when there is at least one message on each port in the Join) that removes the only message on the token port, and a new message is only posted when the handler completes.&lt;/P&gt;
&lt;P&gt;Of course, in order to get the ball rolling I have to post one token onto the token port.&lt;/P&gt;&lt;PRE class=code&gt;    &lt;SPAN class=kwrd&gt;private&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; Init()
    {
        Activate&amp;lt;&lt;SPAN class=type&gt;ITask&lt;/SPAN&gt;&amp;gt;(
            &lt;SPAN class=type&gt;Arbiter&lt;/SPAN&gt;.JoinedReceive&amp;lt;&lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt;, &lt;SPAN class=type&gt;EmptyValue&lt;/SPAN&gt;&amp;gt;(&lt;SPAN class=kwrd&gt;true&lt;/SPAN&gt;, _port, _tokenPort, 
    OnMsg),
            &lt;SPAN class=type&gt;Arbiter&lt;/SPAN&gt;.ReceiveWithIterator&amp;lt;&lt;SPAN class=type&gt;Shutdown&lt;/SPAN&gt;&amp;gt;(&lt;SPAN class=kwrd&gt;false&lt;/SPAN&gt;, _port, OnShutdown)
        );

        &lt;SPAN class=cmt&gt;//&lt;/SPAN&gt;
        &lt;SPAN class=cmt&gt;// Prime the token port&lt;/SPAN&gt;
        &lt;SPAN class=cmt&gt;//&lt;/SPAN&gt;
        _tokenPort.Post(&lt;SPAN class=type&gt;EmptyValue&lt;/SPAN&gt;.SharedInstance);
    }
&lt;/PRE&gt;
&lt;P&gt;The message handler is simplicity itself, Only two things to note here, &lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;If the message is null or empty, I treat this as a command to flush the writer.&lt;/LI&gt;
&lt;LI&gt;The entire functionality of this handler is wrapped in a try...finally construct, and it is in the finally that the new token is posted, so regardless of what happens in handler there is always a token available to that the join can fire for the next message.&lt;/LI&gt;&lt;/OL&gt;&lt;PRE class=code&gt;    &lt;SPAN class=kwrd&gt;private&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; OnMsg(&lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt; msg, &lt;SPAN class=type&gt;EmptyValue&lt;/SPAN&gt; token)
    {
        &lt;SPAN class=kwrd&gt;try&lt;/SPAN&gt;
        {
            &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (&lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt;.IsNullOrEmpty(msg))
            {
                _writer.Flush();
            }
            &lt;SPAN class=kwrd&gt;else&lt;/SPAN&gt;
            {
                _writer.WriteLine(msg);
            }
        }
        &lt;SPAN class=kwrd&gt;finally&lt;/SPAN&gt;
        {
            _tokenPort.Post(token);
        }
    }
&lt;/PRE&gt;
&lt;P&gt;The only other handler is for Shutdown. This is were reason for the token port becomes apparent. The first thing that the handler does is yield to a receiver on the token port, this does two things, firstly it waits for any message currently being logged to be completed and, secondly it prevents any more message from being logged.&lt;/P&gt;
&lt;P&gt;Once the main logging handler is starved, the shutdown handler then removes any messages currently waiting, closes the writer and reports success back to its caller.&lt;/P&gt;&lt;PRE class=code&gt;    &lt;SPAN class=kwrd&gt;private&lt;/SPAN&gt; IEnumerator&amp;lt;&lt;SPAN class=type&gt;ITask&lt;/SPAN&gt;&amp;gt; OnShutdown(&lt;SPAN class=type&gt;Shutdown&lt;/SPAN&gt; shutdown)
    {
        &lt;SPAN class=kwrd&gt;try&lt;/SPAN&gt;
        {
            &lt;SPAN class=cmt&gt;//&lt;/SPAN&gt;
            &lt;SPAN class=cmt&gt;// steal the serialization token, this stops the OnMsg handler from&lt;/SPAN&gt;
            &lt;SPAN class=cmt&gt;// ever being called again.&lt;/SPAN&gt;
            &lt;SPAN class=cmt&gt;//&lt;/SPAN&gt;
            &lt;SPAN class=kwrd&gt;yield&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; &lt;SPAN class=type&gt;Arbiter&lt;/SPAN&gt;.Receive(&lt;SPAN class=kwrd&gt;false&lt;/SPAN&gt;, _tokenPort, EmptyHandler);

            &lt;SPAN class=cmt&gt;//&lt;/SPAN&gt;
            &lt;SPAN class=cmt&gt;// drain the currently outstanding messages, any messages posted&lt;/SPAN&gt;
            &lt;SPAN class=cmt&gt;// after this point will be discarded.&lt;/SPAN&gt;
            &lt;SPAN class=cmt&gt;//&lt;/SPAN&gt;
            DrainMsgPort();

            _writer.Flush();
            _writer.Close();
        }
        &lt;SPAN class=kwrd&gt;finally&lt;/SPAN&gt;
        {
            shutdown.ResultPort.Post(&lt;SPAN class=type&gt;SuccessResult&lt;/SPAN&gt;.Instance);
        }
    }
&lt;/PRE&gt;
&lt;P&gt;This drains messages from the port, only draining the number that were on the port when the function was first called, it is easy to see how not having this kind of limit can create code that may not terminate.&lt;/P&gt;&lt;PRE class=code&gt;    &lt;SPAN class=kwrd&gt;private&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; DrainMsgPort()
    {
        &lt;SPAN class=cmt&gt;//&lt;/SPAN&gt;
        &lt;SPAN class=cmt&gt;// drain the number of messages that were available at the start of this &lt;/SPAN&gt;
        &lt;SPAN class=cmt&gt;// method, anything that arrives later is left for the GC, otherwise&lt;/SPAN&gt;
        &lt;SPAN class=cmt&gt;// this may never terminate.&lt;/SPAN&gt;
        &lt;SPAN class=cmt&gt;//&lt;/SPAN&gt;
        &lt;SPAN class=kwrd&gt;var&lt;/SPAN&gt; max = _port.P0.ItemCount;
        &lt;SPAN class=kwrd&gt;for&lt;/SPAN&gt; (&lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; count = 0; count &amp;lt; max; count++)
        {
            &lt;SPAN class=kwrd&gt;var&lt;/SPAN&gt; msg = _port.Test&amp;lt;&lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt;&amp;gt;();
            &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (!&lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt;.IsNullOrEmpty(msg))
            {
                _writer.WriteLine(msg);
            }
        }
    }
}
&lt;/PRE&gt;
&lt;H2&gt;The Operations Port&lt;/H2&gt;
&lt;P&gt;The operations port is every bit as important as the service code, it is the interface that you use to communicate with the service.&lt;/P&gt;
&lt;P&gt;At its most basic level the&amp;nbsp; port is merely derived from PortSet&amp;lt;string, Shutdown&amp;gt; and that is all that is &lt;I&gt;needed&lt;/I&gt;, but adding some helper functions makes it enormously more useable&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;sealed&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;class&lt;/SPAN&gt; StreamLoggerOperations : &lt;SPAN class=type&gt;PortSet&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt;, &lt;SPAN class=type&gt;Shutdown&lt;/SPAN&gt;&amp;gt;
{
    &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; Log(&lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt; msg)
    {
        Post(msg);
    }

    &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; Log(&lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt; format, &lt;SPAN class=kwrd&gt;params&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;object&lt;/SPAN&gt;[] args)
    {
        Post(&lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt;.Format(format, args));
    }

    &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; Log(&lt;SPAN class=type&gt;IFormatProvider&lt;/SPAN&gt; provider, &lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt; format, &lt;SPAN class=kwrd&gt;params&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;object&lt;/SPAN&gt;[] 
    args)
    {
        Post(&lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt;.Format(provider, format, args));
    }

    &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; Flush()
    {
        Post(&lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt;.Empty);
    }

    &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=type&gt;SuccessFailurePort&lt;/SPAN&gt; &lt;SPAN class=type&gt;Shutdown&lt;/SPAN&gt;()
    {
        &lt;SPAN class=kwrd&gt;var&lt;/SPAN&gt; s = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; &lt;SPAN class=type&gt;Shutdown&lt;/SPAN&gt;();

        Post(s);

        &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; s.ResultPort;
    }
}
&lt;/PRE&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8766074" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/pollrobots/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/pollrobots/archive/tags/CCR/default.aspx">CCR</category><category domain="http://blogs.msdn.com/pollrobots/archive/tags/Utilities/default.aspx">Utilities</category></item><item><title>Using CCR with ASP.NET</title><link>http://blogs.msdn.com/pollrobots/archive/2008/06/09/using-ccr-with-asp-net.aspx</link><pubDate>Tue, 10 Jun 2008 04:42:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8588193</guid><dc:creator>PollRobots</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/pollrobots/comments/8588193.aspx</comments><wfw:commentRss>http://blogs.msdn.com/pollrobots/commentrss.aspx?PostID=8588193</wfw:commentRss><description>
&lt;STYLE type=text/css&gt;
        span.code
        {
            font-family: Consolas, Courier, Monospace;
            font-size: 11px;
            color: #000000;
            background-color: #FFFFFF;
        }
        pre.code
        {
            font-family: Consolas, Courier, Monospace;
            font-size: 11px;
            color: #000000;
            background-color: #FFFFFF;
        }
        span.kwrd
        {
            color: #0000FF;
        }
        span.type
        {
            color: #008080;
        }
        span.str
        {
            color: #800000;
        }
        span.cmt
        {
            color: #008000;
        }
        span.dcmt
        {
            color: #404040;
        }
        span.line
        {
            color: #008080;
            border-right: solid 1 #CCC;
        }
    &lt;/STYLE&gt;

&lt;P&gt;&lt;STRONG&gt;Disclaimer:&lt;/STRONG&gt; While I should be somewhat knowledgable about CCR, I can claim no great familiarity with ASP.NET, so if my approach is a little off, please let me know. &lt;/P&gt;
&lt;P&gt;How to best use CCR within ASP.NET is something that has come up a number of times. Certainly the powerful concurrency and coordination tools that CCR provides make this an obvious question. &lt;/P&gt;
&lt;P&gt;ASP.NET provides a mechanism to run asynchronous tasks, complete with timeout support. When the asynchronous tasks all register completion the page finishes the prerender stage. To make this work with CCR I created an adapter which presents itself to ASP.NET as a classic .Net async task - using the asynchronous programming model (APM), but presents itself to the CCR programmer as a SuccessFailurePort to post a message to when async processing is complete.&lt;/P&gt;
&lt;H1&gt;A Simple Example&lt;/H1&gt;
&lt;P&gt;So, to plunge right in, here is somewhat unrealistic, but simple, example...&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; Page_Load(&lt;SPAN class=kwrd&gt;object&lt;/SPAN&gt; source, &lt;SPAN class=type&gt;EventArgs&lt;/SPAN&gt; e)
{
    TaskQueue = Global.TaskQueue;
    
    &lt;SPAN class=kwrd&gt;var&lt;/SPAN&gt; asyncPort = &lt;SPAN class=kwrd&gt;base&lt;/SPAN&gt;.StartAsyncTask();
    
    &lt;SPAN class=kwrd&gt;var&lt;/SPAN&gt; resultPort = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; &lt;SPAN class=type&gt;SuccessFailurePort&lt;/SPAN&gt;();
    &lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; count = 10;
    &lt;SPAN class=kwrd&gt;for&lt;/SPAN&gt; (&lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; i = 0; i &amp;lt; count; i++)
    {
        SpawnIterator(&lt;SPAN class=str&gt;"http://wwww.microsoft.com"&lt;/SPAN&gt;, resultPort, DownloadUrl);
    }
    
    Activate(
        &lt;SPAN class=type&gt;Arbiter&lt;/SPAN&gt;.MultipleItemReceive(resultPort,
            count,
            (successes, exceptions) =&amp;gt; asyncPort.Post(&lt;SPAN class=type&gt;SuccessResult&lt;/SPAN&gt;.Instance)
        )
    );
}

&lt;SPAN class=type&gt;IEnumerator&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=type&gt;ITask&lt;/SPAN&gt;&amp;gt; DownloadUrl(&lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt; url, &lt;SPAN class=type&gt;SuccessFailurePort&lt;/SPAN&gt; resultPort)
{
    &lt;SPAN class=cmt&gt;// Async processing to download from url.&lt;/SPAN&gt;

    resultPort.Post(&lt;SPAN class=type&gt;SuccessResult&lt;/SPAN&gt;.Instance);
    &lt;SPAN class=kwrd&gt;yield&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;break&lt;/SPAN&gt;;
}

&lt;/PRE&gt;
&lt;P&gt;Breaking this down, there are several things in the preceding code snippet that aren't available in a typical ASP.NET page, what I haven't shown you (yet!) is that the page is derived from a class &lt;SPAN class=code&gt;CcrPage&lt;/SPAN&gt; which gives the page the functionality of the CCR class &lt;SPAN class=code&gt;CcrServiceBase&lt;/SPAN&gt; and a couple of extras that are specific to using CCR with ASP.NET.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;I start by setting &lt;SPAN class=code&gt;TaskQueue = Global.TaskQueue;&lt;/SPAN&gt; It is essential to set the &lt;SPAN class=code&gt;TaskQueue&lt;/SPAN&gt; property any time you want to use CCR primitives in the page. I usually set it in &lt;SPAN class=code&gt;Page_Load()&lt;/SPAN&gt;, that way I always know it is set...&lt;/LI&gt;
&lt;LI&gt;Where do I get &lt;SPAN class=code&gt;Global.TaskQueue&lt;/SPAN&gt; from? It is most efficient to associate the CCR Dispatcher and DispatcherQueues with the Application, rather than the page. So I have created a class, &lt;SPAN class=code&gt;CcrHttpApplication&lt;/SPAN&gt;,that inherits from &lt;SPAN class=code&gt;HttpApplication&lt;/SPAN&gt;. More on this in a bit. &lt;/LI&gt;
&lt;LI&gt;I call &lt;SPAN class=code&gt;&lt;SPAN class=kwrd&gt;base&lt;/SPAN&gt;.StartAsyncTask();&lt;/SPAN&gt; – this is implemented by the base class &lt;SPAN class=code&gt;CcrPage&lt;/SPAN&gt; and internally calls the &lt;SPAN class=code&gt;RegisterAsyncTask&lt;/SPAN&gt; method, which lets ASP.NET know that this page is doing asynchronous processing. It returns a &lt;SPAN class=code&gt;SuccessFailurePort&lt;/SPAN&gt; which I post to when all the asynchronous processing is complete. This in turn lets the ASP.NET infrastructure know that the async processing is finished.&lt;/LI&gt;
&lt;LI&gt;I use CCR primitives like &lt;SPAN class=code&gt;SpawnIterator()&lt;/SPAN&gt; and &lt;SPAN class=code&gt;Activate()&lt;/SPAN&gt;, these again are implemented in &lt;SPAN class=code&gt;CcrPage&lt;/SPAN&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;The iterator method &lt;SPAN class=code&gt;DownloadUrl&lt;/SPAN&gt; asynchronously downloads a page from the supplied URL and, when it has completed, posts a result to the supplied port. Note that in &lt;SPAN class=code&gt;Page_Load()&lt;/SPAN&gt; I activate a MultiItemReceive task that will execute when every instance of &lt;SPAN class=code&gt;DownloadUrl&lt;/SPAN&gt; has completed. This is a typical scatter-gather pattern that is so easy to implement using CCR.&lt;/P&gt;
&lt;P&gt;When all the &lt;SPAN class=code&gt;DownloadUrl&lt;/SPAN&gt; calls have posted a result, that task then posts to the &lt;SPAN class=code&gt;SuccessFailurePort&lt;/SPAN&gt; initially created by the call to &lt;SPAN class=code&gt;StartAsyncTask();&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2&gt;A Simple Asynchronous Task&lt;/H2&gt;
&lt;P&gt;As a small diversion, and for completeness sake, here is the actual code for &lt;SPAN class=code&gt;DownloadUrl()&lt;/SPAN&gt;. Feel free to skip ahead the CcrPage implementation if this is uninteresting...&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN class=type&gt;IEnumerator&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=type&gt;ITask&lt;/SPAN&gt;&amp;gt; DownloadUrl(&lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt; url, &lt;SPAN class=type&gt;SuccessFailurePort&lt;/SPAN&gt; resultPort)
{
    &lt;SPAN class=type&gt;IAsyncResult&lt;/SPAN&gt; result = &lt;SPAN class=kwrd&gt;null&lt;/SPAN&gt;;
    &lt;SPAN class=kwrd&gt;var&lt;/SPAN&gt; completion = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; &lt;SPAN class=type&gt;Port&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=type&gt;IAsyncResult&lt;/SPAN&gt;&amp;gt;();

    &lt;SPAN class=kwrd&gt;var&lt;/SPAN&gt; request = &lt;SPAN class=type&gt;WebRequest&lt;/SPAN&gt;.Create(&lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; &lt;SPAN class=type&gt;Uri&lt;/SPAN&gt;(url));
    request.BeginGetResponse(completion.Post, &lt;SPAN class=kwrd&gt;null&lt;/SPAN&gt;);

    &lt;SPAN class=kwrd&gt;yield&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; &lt;SPAN class=type&gt;Arbiter&lt;/SPAN&gt;.Choice(
        &lt;SPAN class=type&gt;Arbiter&lt;/SPAN&gt;.Receive(&lt;SPAN class=kwrd&gt;false&lt;/SPAN&gt;, completion, ar =&amp;gt; result = ar),
        OnAsyncTimeout()
    );
&lt;/PRE&gt;
&lt;P&gt;This demonstrates a useful CCR trick when working with APM. The delegate for the &lt;SPAN class=code&gt;Begin()&lt;/SPAN&gt; method is the &lt;SPAN class=code&gt;Post&lt;/SPAN&gt; method on a port of type &lt;SPAN class=code&gt;Port&amp;lt;IAsyncResult&amp;gt;&lt;/SPAN&gt;, this allows me to yield until the method has completed. In this example I'm using a &lt;SPAN class=code&gt;Choice&lt;/SPAN&gt; and in the second branch waiting for a timeout. The &lt;SPAN class=code&gt;OnAsyncTimeout()&lt;/SPAN&gt; method in &lt;SPAN class=code&gt;CcrPage&lt;/SPAN&gt; will execute if the page timeout fires. This allows me to prevent runaway async processing.&lt;/P&gt;
&lt;P&gt;So far the code has initiated a request for a web page, and is waiting for it to complete, in which case result will be set the the &lt;SPAN class=code&gt;IAsyncResult&lt;/SPAN&gt;, or for the default page timeout.&lt;/P&gt;&lt;PRE class=code&gt;    &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (result == &lt;SPAN class=kwrd&gt;null&lt;/SPAN&gt;)
    {
        &lt;SPAN class=cmt&gt;// page timeout occurred...&lt;/SPAN&gt;
        resultPort.Post(&lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; &lt;SPAN class=type&gt;TimeoutException&lt;/SPAN&gt;());
        request.Abort();
        &lt;SPAN class=kwrd&gt;yield&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;break&lt;/SPAN&gt;;
    }
&lt;/PRE&gt;
&lt;P&gt;This has just checked for a timeout. If a timeout occured, this signals an exception back to the async port, aborts the web request and terminates the iterator. All being well, however, we continue below...&lt;/P&gt;&lt;PRE class=code&gt;    &lt;SPAN class=type&gt;WebResponse&lt;/SPAN&gt; response = &lt;SPAN class=kwrd&gt;null&lt;/SPAN&gt;;

    &lt;SPAN class=kwrd&gt;try&lt;/SPAN&gt;
    {
        response = request.EndGetResponse(result);
    }
    &lt;SPAN class=kwrd&gt;catch&lt;/SPAN&gt; (&lt;SPAN class=type&gt;Exception&lt;/SPAN&gt; exception)
    {
        resultPort.Post(exception);
        &lt;SPAN class=kwrd&gt;yield&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;break&lt;/SPAN&gt;;
    }&lt;/PRE&gt;
&lt;P&gt;This now uses the &lt;SPAN class=code&gt;IAsyncResult&lt;/SPAN&gt; that was posted to the completion port and ends the web request. Assuming that this doesn't throw an exception in its own right, we can now continue below in much the same fashion and, using the APM for reading from a stream, download the entire page before posting a response. &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Note:&lt;/STRONG&gt; at any point in this processing, we can be interrupted by a timeout, or by a failure in the APM, and still cleanly recover.&lt;/P&gt;&lt;PRE class=code&gt;    &lt;SPAN class=kwrd&gt;var&lt;/SPAN&gt; stream = response.GetResponseStream();

    &lt;SPAN class=kwrd&gt;using&lt;/SPAN&gt; (&lt;SPAN class=kwrd&gt;var&lt;/SPAN&gt; memory = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; MemoryStream())
    {
        &lt;SPAN class=kwrd&gt;var&lt;/SPAN&gt; buffer = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;byte&lt;/SPAN&gt;[4096];
        &lt;SPAN class=kwrd&gt;var&lt;/SPAN&gt; read = 0;
        &lt;SPAN class=kwrd&gt;do&lt;/SPAN&gt;
        {
            stream.BeginRead(buffer, 0, buffer.Length, completion.Post, &lt;SPAN class=kwrd&gt;null&lt;/SPAN&gt;);

            result = &lt;SPAN class=kwrd&gt;null&lt;/SPAN&gt;;
            &lt;SPAN class=kwrd&gt;yield&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; &lt;SPAN class=type&gt;Arbiter&lt;/SPAN&gt;.Choice(
                &lt;SPAN class=type&gt;Arbiter&lt;/SPAN&gt;.Receive(&lt;SPAN class=kwrd&gt;false&lt;/SPAN&gt;, completion, ar =&amp;gt; result = ar),
                OnAsyncTimout()
            );

            &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (result == &lt;SPAN class=kwrd&gt;null&lt;/SPAN&gt;)
            {
                resultPort.Post(&lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; &lt;SPAN class=type&gt;TimeoutException&lt;/SPAN&gt;());
                &lt;SPAN class=kwrd&gt;yield&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;break&lt;/SPAN&gt;;
            }

            read = stream.EndRead(result);
            memory.Write(buffer, 0, read);

        } &lt;SPAN class=kwrd&gt;while&lt;/SPAN&gt; (read == buffer.Length);
    }

    resultPort.Post(&lt;SPAN class=type&gt;SuccessResult&lt;/SPAN&gt;.Instance);
}
&lt;/PRE&gt;
&lt;H1&gt;CcrPage Implementation&lt;/H1&gt;
&lt;P&gt;The page used above, instead of being derived from &lt;SPAN class=code&gt;System.Web.UI.Page&lt;/SPAN&gt;, was derived from &lt;SPAN class=code&gt;CcrPage&lt;/SPAN&gt; (coming soon to a Ccr Adapter near you), which looks somewhat like the following (ok, so I've left a lot out to keep the sample smaller, but the core functionality is all here)&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;class&lt;/SPAN&gt; &lt;SPAN class=type&gt;CcrPage&lt;/SPAN&gt; : &lt;SPAN class=type&gt;Page&lt;/SPAN&gt;
{
    &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=type&gt;CcrPage&lt;/SPAN&gt;() { }

    &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=type&gt;CcrPage&lt;/SPAN&gt;(&lt;SPAN class=type&gt;DispatcherQueue&lt;/SPAN&gt; taskQueue)
    {
        TaskQueue = taskQueue;
    }

    &lt;SPAN class=kwrd&gt;protected&lt;/SPAN&gt; &lt;SPAN class=type&gt;DispatcherQueue&lt;/SPAN&gt; TaskQueue;
&lt;/PRE&gt;
&lt;P&gt;Basic class constructors, the infamous &lt;SPAN class=code&gt;TaskQueue&lt;/SPAN&gt; field, you'll notice that being used a lot below. Using CCR without a ServiceBase class is, of course, a totally reasonable thing to do, but I find that the helper methods reduce code and increase readability.&lt;/P&gt;
&lt;P&gt;The next section is just implementing the helper functionality from &lt;SPAN class=code&gt;CcrServiceBase&lt;/SPAN&gt;. If you are familiar with CCR programming this is all pretty self explanatory. For simplicity, I've not included all the overloads here, but all the basics are shown...&lt;/P&gt;&lt;PRE class=code&gt;    &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; Activate&amp;lt;T&amp;gt;(&lt;SPAN class=kwrd&gt;params&lt;/SPAN&gt; T[] tasks)
        &lt;SPAN class=kwrd&gt;where&lt;/SPAN&gt; T : &lt;SPAN class=type&gt;ITask&lt;/SPAN&gt;
    {
        &lt;SPAN class=kwrd&gt;foreach&lt;/SPAN&gt; (T task &lt;SPAN class=kwrd&gt;in&lt;/SPAN&gt; tasks)
        {
            TaskQueue.Enqueue(task);
        }
    }

    &lt;SPAN class=kwrd&gt;protected&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; Spawn(&lt;SPAN class=type&gt;Handler&lt;/SPAN&gt; handler)
    {
        TaskQueue.Enqueue(&lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; &lt;SPAN class=type&gt;Task&lt;/SPAN&gt;(handler));
    }

    &lt;SPAN class=kwrd&gt;protected&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; Spawn&amp;lt;T0&amp;gt;(T0 t0, &lt;SPAN class=type&gt;Handler&lt;/SPAN&gt;&amp;lt;T0&amp;gt; handler)
    {
        TaskQueue.Enqueue(&lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; &lt;SPAN class=type&gt;Task&lt;/SPAN&gt;&amp;lt;T0&amp;gt;(t0, handler));
    }

    &lt;SPAN class=kwrd&gt;protected&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; SpawnIterator&amp;lt;T0&amp;gt;(T0 t0, &lt;SPAN class=type&gt;IteratorHandler&lt;/SPAN&gt;&amp;lt;T0&amp;gt; handler)
    {
        TaskQueue.Enqueue(&lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; &lt;SPAN class=type&gt;IterativeTask&lt;/SPAN&gt;&amp;lt;T0&amp;gt;(t0, handler));
    }

    &lt;SPAN class=kwrd&gt;protected&lt;/SPAN&gt; &lt;SPAN class=type&gt;Port&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=type&gt;DateTime&lt;/SPAN&gt;&amp;gt; TimeoutPort(&lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; milliseconds)
    {
        &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; TimeoutPort(&lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; &lt;SPAN class=type&gt;TimeSpan&lt;/SPAN&gt;(0, 0, 0, 0, milliseconds));
    }

    &lt;SPAN class=kwrd&gt;protected&lt;/SPAN&gt; &lt;SPAN class=type&gt;Port&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=type&gt;DateTime&lt;/SPAN&gt;&amp;gt; TimeoutPort(&lt;SPAN class=type&gt;TimeSpan&lt;/SPAN&gt; timespan)
    {
        &lt;SPAN class=type&gt;Port&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=type&gt;DateTime&lt;/SPAN&gt;&amp;gt; timeoutPort = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; &lt;SPAN class=type&gt;Port&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=type&gt;DateTime&lt;/SPAN&gt;&amp;gt;();
        TaskQueue.EnqueueTimer(timespan, timeoutPort);
        &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; timeoutPort;
    }
&lt;/PRE&gt;
&lt;P&gt;This is where it starts to get a little more interesting, these are the methods that allow us to play well in the ASP.NET world.&lt;/P&gt;&lt;PRE class=code&gt;    &lt;SPAN class=kwrd&gt;protected&lt;/SPAN&gt; &lt;SPAN class=type&gt;SuccessFailurePort&lt;/SPAN&gt; StartAsyncTask()
    {
        &lt;SPAN class=type&gt;SuccessFailurePort&lt;/SPAN&gt; resultPort = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; &lt;SPAN class=type&gt;SuccessFailurePort&lt;/SPAN&gt;();
        &lt;SPAN class=type&gt;Dispatcher&lt;/SPAN&gt;.AddCausality(&lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; &lt;SPAN class=type&gt;Causality&lt;/SPAN&gt;(&lt;SPAN class=str&gt;"StartAsyncTask"&lt;/SPAN&gt;, resultPort));

        RegisterAsyncTask(
            &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; &lt;SPAN class=type&gt;PageAsyncTask&lt;/SPAN&gt;(
                OnBeginTask,
                OnEndTask,
                OnTimeoutTask,
                resultPort
            )
        );

        &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; resultPort;
    }
&lt;/PRE&gt;
&lt;P&gt;&lt;SPAN class=code&gt;StartAsyncTask&lt;/SPAN&gt; wraps the ASP.NET &lt;SPAN class=code&gt;RegisterAsyncTask&lt;/SPAN&gt; to allow us to use CCR primitives to control the lifecycle of the async processing that we want to do. The code below should demonstrate and explain how I accomplish this.&lt;/P&gt;
&lt;P&gt;Adding a Causality to the dispatcher at this point allows me to catch any unhandled exceptions in the async processing in a clean fashion and report them back using the normal ASP.NET error mechanisms.&lt;/P&gt;&lt;PRE class=code&gt;    
    &lt;SPAN class=kwrd&gt;protected&lt;/SPAN&gt; &lt;SPAN class=type&gt;Port&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=type&gt;EmptyValue&lt;/SPAN&gt;&amp;gt; AsyncTaskTimeoutPort = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; &lt;SPAN class=type&gt;Port&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=type&gt;EmptyValue&lt;/SPAN&gt;&amp;gt;();

    &lt;SPAN class=kwrd&gt;protected&lt;/SPAN&gt; ReceiverTask OnAsyncTimeout(&lt;SPAN class=type&gt;Handler&lt;/SPAN&gt; handler)
    {
        &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; &lt;SPAN class=type&gt;Arbiter&lt;/SPAN&gt;.Receive(
            &lt;SPAN class=kwrd&gt;false&lt;/SPAN&gt;,
            AsyncTaskTimeoutPort,
            &lt;SPAN class=kwrd&gt;delegate&lt;/SPAN&gt;(&lt;SPAN class=type&gt;EmptyValue&lt;/SPAN&gt; token)
            {
                AsyncTaskTimeoutPort.Post(token);
                handler();
            }
        );
    }

    &lt;SPAN class=kwrd&gt;protected&lt;/SPAN&gt; ReceiverTask OnAsyncTimout()
    {
        &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; &lt;SPAN class=type&gt;Arbiter&lt;/SPAN&gt;.Receive(
            &lt;SPAN class=kwrd&gt;false&lt;/SPAN&gt;,
            AsyncTaskTimeoutPort,
            &lt;SPAN class=kwrd&gt;delegate&lt;/SPAN&gt;(&lt;SPAN class=type&gt;EmptyValue&lt;/SPAN&gt; token)
            {
                AsyncTaskTimeoutPort.Post(token);
            }
        );
    }
&lt;/PRE&gt;
&lt;P&gt;These two helper functions make responding to page level timeouts easier in your CCR code. The simpler helper was used in the implementation of &lt;SPAN class=code&gt;DownloadUrl()&lt;/SPAN&gt; above.&lt;/P&gt;&lt;PRE class=code&gt;    &lt;SPAN class=kwrd&gt;class&lt;/SPAN&gt; &lt;SPAN class=type&gt;SimpleAsyncResult&lt;/SPAN&gt; : &lt;SPAN class=type&gt;IAsyncResult&lt;/SPAN&gt;
    {
        &lt;SPAN class=type&gt;ManualResetEvent&lt;/SPAN&gt; _event = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; &lt;SPAN class=type&gt;ManualResetEvent&lt;/SPAN&gt;(&lt;SPAN class=kwrd&gt;false&lt;/SPAN&gt;);
        &lt;SPAN class=type&gt;AsyncCallback&lt;/SPAN&gt; _cb;
        &lt;SPAN class=kwrd&gt;object&lt;/SPAN&gt; _state;
        &lt;SPAN class=type&gt;Exception&lt;/SPAN&gt; _exception;

        &lt;SPAN class=kwrd&gt;internal&lt;/SPAN&gt; &lt;SPAN class=type&gt;SimpleAsyncResult&lt;/SPAN&gt;(&lt;SPAN class=type&gt;AsyncCallback&lt;/SPAN&gt; cb, &lt;SPAN class=kwrd&gt;object&lt;/SPAN&gt; state)
        {
            _cb = cb;
            _state = state;
        }

        &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;object&lt;/SPAN&gt; AsyncState { &lt;SPAN class=kwrd&gt;get&lt;/SPAN&gt; { &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; _state; } }

        &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=type&gt;WaitHandle&lt;/SPAN&gt; AsyncWaitHandle { &lt;SPAN class=kwrd&gt;get&lt;/SPAN&gt; { &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; _event; } }

        &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;bool&lt;/SPAN&gt; CompletedSynchronously { &lt;SPAN class=kwrd&gt;get&lt;/SPAN&gt; { &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;false&lt;/SPAN&gt;; } }

        &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;bool&lt;/SPAN&gt; IsCompleted
        {
            &lt;SPAN class=kwrd&gt;get&lt;/SPAN&gt; { &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; _event.WaitOne(0, &lt;SPAN class=kwrd&gt;false&lt;/SPAN&gt;); }
        }

        &lt;SPAN class=kwrd&gt;internal&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; Complete(&lt;SPAN class=type&gt;SuccessResult&lt;/SPAN&gt; success)
        {
            InternalComplete();
        }

        &lt;SPAN class=kwrd&gt;internal&lt;/SPAN&gt; &lt;SPAN class=type&gt;Exception&lt;/SPAN&gt; &lt;SPAN class=type&gt;Exception&lt;/SPAN&gt; { &lt;SPAN class=kwrd&gt;get&lt;/SPAN&gt; { &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; _exception; } }

        &lt;SPAN class=kwrd&gt;internal&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; Complete(&lt;SPAN class=type&gt;Exception&lt;/SPAN&gt; exception)
        {
            _exception = exception;
            InternalComplete();
        }

        &lt;SPAN class=kwrd&gt;private&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; InternalComplete()
        {
            _event.Set();
            _cb.Invoke(&lt;SPAN class=kwrd&gt;this&lt;/SPAN&gt;);
        }
    }
&lt;/PRE&gt;
&lt;P&gt;&lt;SPAN class=code&gt;SimpleAsyncResult&lt;/SPAN&gt; is an internal class used to help implement the APM that &lt;SPAN class=code&gt;RegisterAsyncTask&lt;/SPAN&gt; expects&lt;/P&gt;&lt;PRE class=code&gt;    &lt;SPAN class=type&gt;IAsyncResult&lt;/SPAN&gt; OnBeginTask(&lt;SPAN class=kwrd&gt;object&lt;/SPAN&gt; sender, &lt;SPAN class=type&gt;EventArgs&lt;/SPAN&gt; e, &lt;SPAN class=type&gt;AsyncCallback&lt;/SPAN&gt; cb, &lt;SPAN class=kwrd&gt;object&lt;/SPAN&gt; state)
    {
        &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (state == &lt;SPAN class=kwrd&gt;null&lt;/SPAN&gt;)
        {
            &lt;SPAN class=kwrd&gt;throw&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; &lt;SPAN class=type&gt;ArgumentNullException&lt;/SPAN&gt;();
        }
        &lt;SPAN class=type&gt;SuccessFailurePort&lt;/SPAN&gt; resultPort = state &lt;SPAN class=kwrd&gt;as&lt;/SPAN&gt; &lt;SPAN class=type&gt;SuccessFailurePort&lt;/SPAN&gt;;
        &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (resultPort == &lt;SPAN class=kwrd&gt;null&lt;/SPAN&gt;)
        {
            &lt;SPAN class=kwrd&gt;throw&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; &lt;SPAN class=type&gt;ArgumentException&lt;/SPAN&gt;();
        }

        &lt;SPAN class=type&gt;SimpleAsyncResult&lt;/SPAN&gt; ar = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; &lt;SPAN class=type&gt;SimpleAsyncResult&lt;/SPAN&gt;(cb, state);

        Activate(&lt;SPAN class=type&gt;Arbiter&lt;/SPAN&gt;.Choice(resultPort, ar.Complete, ar.Complete));

        &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; ar;
    }
&lt;/PRE&gt;
&lt;P&gt;This is called at the start of the async processing and sets up the &lt;SPAN class=code&gt;SimpleAsyncResult&lt;/SPAN&gt; instance that is used to manage the lifetime of the async processing. &lt;/P&gt;
&lt;P&gt;This ultimately activates a &lt;SPAN class=code&gt;Choice&lt;/SPAN&gt; that waits for either a &lt;SPAN class=code&gt;SuccessResult&lt;/SPAN&gt; or &lt;SPAN class=code&gt;Exception&lt;/SPAN&gt; to be posted to the &lt;SPAN class=code&gt;SuccessFailurePort&lt;/SPAN&gt; that was created in &lt;SPAN class=code&gt;StartAsyncTask()&lt;/SPAN&gt;. The branches of the choice each call different overloads of the &lt;SPAN class=code&gt;Complete()&lt;/SPAN&gt; method on the &lt;SPAN class=code&gt;SimpleAsyncResult&lt;/SPAN&gt; object.&lt;/P&gt;&lt;PRE class=code&gt;    &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; OnEndTask(&lt;SPAN class=type&gt;IAsyncResult&lt;/SPAN&gt; ar)
    {
        &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (ar == &lt;SPAN class=kwrd&gt;null&lt;/SPAN&gt;)
        {
            &lt;SPAN class=kwrd&gt;throw&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; &lt;SPAN class=type&gt;ArgumentNullException&lt;/SPAN&gt;();
        }
        &lt;SPAN class=kwrd&gt;var&lt;/SPAN&gt; sar = ar &lt;SPAN class=kwrd&gt;as&lt;/SPAN&gt; &lt;SPAN class=type&gt;SimpleAsyncResult&lt;/SPAN&gt;;
        &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (sar == &lt;SPAN class=kwrd&gt;null&lt;/SPAN&gt;)
        {
            &lt;SPAN class=kwrd&gt;throw&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; &lt;SPAN class=type&gt;ArgumentException&lt;/SPAN&gt;();
        }
        &lt;SPAN class=kwrd&gt;else&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (sar.IsCompleted)
        {
            &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (sar.Exception != &lt;SPAN class=kwrd&gt;null&lt;/SPAN&gt;)
            {
                &lt;SPAN class=kwrd&gt;throw&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; &lt;SPAN class=type&gt;Exception&lt;/SPAN&gt;(&lt;SPAN class=str&gt;"Failure during asynchronous processing"&lt;/SPAN&gt;, sar.Exception);
            }
        }
        &lt;SPAN class=kwrd&gt;else&lt;/SPAN&gt;
        {
            &lt;SPAN class=kwrd&gt;throw&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; &lt;SPAN class=type&gt;InvalidOperationException&lt;/SPAN&gt;(&lt;SPAN class=str&gt;"OnEndTask called before the asynchronous processing has completed"&lt;/SPAN&gt;);
        }
    }
&lt;/PRE&gt;
&lt;P&gt;This handles all the various termination conditions. In the most common success case this does nothing!&lt;/P&gt;&lt;PRE class=code&gt;    &lt;SPAN class=kwrd&gt;bool&lt;/SPAN&gt; _asyncTimedOut;

    &lt;SPAN class=kwrd&gt;protected&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;bool&lt;/SPAN&gt; AsyncOperationTimedOut
    {
        &lt;SPAN class=kwrd&gt;get&lt;/SPAN&gt; { &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; _asyncTimedOut; }
    }

    &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; OnTimeoutTask(&lt;SPAN class=type&gt;IAsyncResult&lt;/SPAN&gt; ar)
    {
        _asyncTimedOut = &lt;SPAN class=kwrd&gt;true&lt;/SPAN&gt;;
        AsyncTaskTimeoutPort.Post(&lt;SPAN class=type&gt;EmptyValue&lt;/SPAN&gt;.SharedInstance);
    }
}
&lt;/PRE&gt;
&lt;P&gt;And finally, the timeout handling. This sets a flag on the class to indicate that there was a timeout and posts to an internal port (used by &lt;SPAN class=code&gt;OnAsyncTimeout&lt;/SPAN&gt; above) to inform waiting tasks that there was a timeout.&lt;/P&gt;
&lt;H1&gt;CcrHttpApplication Implementation&lt;/H1&gt;
&lt;P&gt;As I mentioned above, it is more useful to associate the Dispatcher and DispatcherQueue with the application than with a page, so I add a &lt;SPAN class=code&gt;Global.asax&lt;/SPAN&gt; to my project and instead of deriving it from &lt;SPAN class=code&gt;System.Web.HttpApplication&lt;/SPAN&gt;, I derive it from &lt;SPAN class=code&gt;CcrHttpApplication&lt;/SPAN&gt;, shown below&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;class&lt;/SPAN&gt; &lt;SPAN class=type&gt;CcrHttpApplication&lt;/SPAN&gt; : &lt;SPAN class=type&gt;HttpApplication&lt;/SPAN&gt;
{
    &lt;SPAN class=kwrd&gt;static&lt;/SPAN&gt; &lt;SPAN class=type&gt;Dispatcher&lt;/SPAN&gt; _dispatcher;
    &lt;SPAN class=kwrd&gt;static&lt;/SPAN&gt; &lt;SPAN class=type&gt;DispatcherQueue&lt;/SPAN&gt; _taskQueue;
    &lt;SPAN class=kwrd&gt;static&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;object&lt;/SPAN&gt; _dispatcherLock = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;object&lt;/SPAN&gt;();

    &lt;SPAN class=kwrd&gt;static&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=type&gt;DispatcherQueue&lt;/SPAN&gt; TaskQueue
    {
        &lt;SPAN class=kwrd&gt;get&lt;/SPAN&gt; { &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; _taskQueue; }
    }
&lt;/PRE&gt;
&lt;P&gt;With all the basic initialization and property accessors out of the way, we can move onto the functionality of this class...&lt;/P&gt;&lt;PRE class=code&gt;    &lt;SPAN class=kwrd&gt;protected&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; Initialize()
    {
        Initialize(0, GetType().Name);
    }

    &lt;SPAN class=kwrd&gt;protected&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; Initialize(&lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; threadCount)
    {
        Initialize(threadCount, GetType().Name);
    }

    &lt;SPAN class=kwrd&gt;protected&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; Initialize(&lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; threadCount, &lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt; threadPoolName)
    {
        &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (_dispatcher == &lt;SPAN class=kwrd&gt;null&lt;/SPAN&gt;)
        {
            &lt;SPAN class=kwrd&gt;lock&lt;/SPAN&gt; (_dispatcherLock)
            {
                &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (_dispatcher == &lt;SPAN class=kwrd&gt;null&lt;/SPAN&gt;)
                {
                    _dispatcher = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; &lt;SPAN class=type&gt;Dispatcher&lt;/SPAN&gt;(threadCount, threadPoolName);
                    _taskQueue = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; &lt;SPAN class=type&gt;DispatcherQueue&lt;/SPAN&gt;(&lt;SPAN class=str&gt;"default"&lt;/SPAN&gt;, _dispatcher);
                }
            }
        }
    }
&lt;/PRE&gt;
&lt;P&gt;This creates a new Dispatcher and default DispatcherQueue. One of the &lt;SPAN class=code&gt;Initialize()&lt;/SPAN&gt; overloads should be called from &lt;SPAN class=code&gt;Application_Start()&lt;/SPAN&gt;&lt;/P&gt;&lt;PRE class=code&gt;    &lt;SPAN class=kwrd&gt;protected&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; &lt;SPAN class=type&gt;Shutdown&lt;/SPAN&gt;()
    {
        &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (_dispatcher != &lt;SPAN class=kwrd&gt;null&lt;/SPAN&gt;)
        {
            &lt;SPAN class=kwrd&gt;lock&lt;/SPAN&gt; (_dispatcherLock)
            {
                &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (_dispatcher != &lt;SPAN class=kwrd&gt;null&lt;/SPAN&gt;)
                {
                    _taskQueue.Dispose();
                    _dispatcher.Dispose();

                    _taskQueue = &lt;SPAN class=kwrd&gt;null&lt;/SPAN&gt;;
                    _dispatcher = &lt;SPAN class=kwrd&gt;null&lt;/SPAN&gt;;
                }
            }
        }
    }
}
&lt;/PRE&gt;
&lt;P&gt;This cleanly disposes any created Dispatcher and DispatcherQueue, and should be called from &lt;SPAN class=code&gt;Application_End()&lt;/SPAN&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8588193" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/pollrobots/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/pollrobots/archive/tags/CCR/default.aspx">CCR</category><category domain="http://blogs.msdn.com/pollrobots/archive/tags/ASP.NET/default.aspx">ASP.NET</category></item><item><title>Pursuit Camera Service (part II)</title><link>http://blogs.msdn.com/pollrobots/archive/2008/04/24/pursuit-camera-service-part-ii.aspx</link><pubDate>Fri, 25 Apr 2008 01:41:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8422940</guid><dc:creator>PollRobots</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/pollrobots/comments/8422940.aspx</comments><wfw:commentRss>http://blogs.msdn.com/pollrobots/commentrss.aspx?PostID=8422940</wfw:commentRss><description>&lt;IMG title="Pursuit Camera Icon" style="WIDTH: 64px; HEIGHT: 64px" height=64 alt="Pursuit Camera Icon" src="http://blogs.msdn.com/photos/pollrobots/images/8422611/original.aspx" width=64 align=right mce_src="http://blogs.msdn.com/photos/pollrobots/images/8422611/original.aspx"&gt; 
&lt;P&gt;When I finished the&amp;nbsp;pursuit camera service,&amp;nbsp;I&amp;nbsp;was unhappy with some&amp;nbsp;aspects of it. Fixing them requires&amp;nbsp;implementing the camera as an entity. Most importantly this allows me to update the position every frame and requires the camera to not be the main camera. As a nice consequence implementing this as an entity allows the camera to play well with the record and playback functionality.&lt;/P&gt;
&lt;P&gt;Implementing a new camera entity is easy. I just create a new C# file in my existing Pursuit Camera project and add a new class which derives from CameraEntity. &lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;&lt;FONT color=#0000ff&gt;namespace&lt;/FONT&gt; Robotics.PursuitCamera 
{ 
    [&lt;FONT color=#2b91af&gt;DataContract&lt;/FONT&gt;] 
    &lt;FONT color=#0000ff&gt;public class&lt;/FONT&gt; &lt;FONT color=#2b91af&gt;PursuitCameraEntity&lt;/FONT&gt; : &lt;FONT color=#2b91af&gt;CameraEntity&lt;/FONT&gt; 
    { 
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;H1&gt;Configuration&lt;/H1&gt;
&lt;P&gt;To configure the entity it needs properties that define its behavior&lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;        &lt;FONT color=#0000ff&gt;string&lt;/FONT&gt; _targetName;
        [&lt;FONT color=#2b91af&gt;DataMember&lt;/FONT&gt;, &lt;FONT size=+0&gt;Browsable&lt;/FONT&gt;(&lt;FONT color=#0000ff&gt;true&lt;/FONT&gt;), &lt;FONT color=#2b91af&gt;Description&lt;/FONT&gt;(&lt;FONT color=#800000&gt;"Name of the entity to track"&lt;/FONT&gt;)]
        &lt;FONT color=#0000ff&gt;public string&lt;/FONT&gt; TargetName 
        { 
            &lt;FONT color=#0000ff&gt;get&lt;/FONT&gt;
            {
                &lt;FONT color=#0000ff&gt;return&lt;/FONT&gt; _targetName;
            }
            &lt;FONT color=#0000ff&gt;set&lt;/FONT&gt;
            {
                &lt;FONT color=#0000ff&gt;if&lt;/FONT&gt; (&lt;FONT color=#0000ff&gt;value&lt;/FONT&gt; != _targetName)
                {
                    _targetName = &lt;FONT color=#0000ff&gt;value&lt;/FONT&gt;;
                    FindTarget();
                }
            } 
        }

        [&lt;FONT color=#2b91af&gt;DataMember&lt;/FONT&gt;, &lt;FONT size=+0&gt;Browsable&lt;/FONT&gt;(&lt;FONT color=#0000ff&gt;true&lt;/FONT&gt;), &lt;FONT color=#2b91af&gt;Description&lt;/FONT&gt;(&lt;FONT color=#800000&gt;"Minimum distance to keep the camera from the entity"&lt;/FONT&gt;)]
        &lt;FONT color=#0000ff&gt;public float&lt;/FONT&gt; MinDistance { &lt;FONT color=#0000ff&gt;get&lt;/FONT&gt;; &lt;FONT color=#0000ff&gt;set&lt;/FONT&gt;; }
        
        [&lt;FONT color=#2b91af&gt;DataMember&lt;/FONT&gt;, &lt;FONT size=+0&gt;Browsable&lt;/FONT&gt;(&lt;FONT color=#0000ff&gt;true&lt;/FONT&gt;), &lt;FONT color=#2b91af&gt;Description&lt;/FONT&gt;(&lt;FONT color=#800000&gt;"Maximum distance to keep the camera from the entity"&lt;/FONT&gt;)]
        &lt;FONT color=#0000ff&gt;public float&lt;/FONT&gt; MaxDistance { &lt;FONT color=#0000ff&gt;get&lt;/FONT&gt;; &lt;FONT color=#0000ff&gt;set&lt;/FONT&gt;; }
        
        [&lt;FONT color=#2b91af&gt;DataMember&lt;/FONT&gt;, &lt;FONT size=+0&gt;Browsable&lt;/FONT&gt;(&lt;FONT color=#0000ff&gt;true&lt;/FONT&gt;), &lt;FONT color=#2b91af&gt;Description&lt;/FONT&gt;(&lt;FONT color=#800000&gt;"Height above ground plane to keep the camera"&lt;/FONT&gt;)]
        &lt;FONT color=#0000ff&gt;public float&lt;/FONT&gt; Altitude { &lt;FONT color=#0000ff&gt;get&lt;/FONT&gt;; &lt;FONT color=#0000ff&gt;set&lt;/FONT&gt;; }

&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;These properties clearly define the essential minimum information that the entity needs to track a target. The name of the target is, as before, the entity name to target, the&amp;nbsp;other properties should be fairly obvious.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Note&lt;/STRONG&gt;: the setter for TargetName calls a method &lt;CODE&gt;FindTarget()&lt;/CODE&gt;, I'll come back to that when I discuss the initialization code.&lt;/P&gt;
&lt;H1&gt;Constructing the Entity&lt;/H1&gt;
&lt;P&gt;Simulation entities typically get constructed in one of two scenarios.&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;A simulation scene is being loaded from file and deserialized. In this case a default constructor is called and all the members are populated by the deserialization code.&lt;/LI&gt;
&lt;LI&gt;The entity is being created from the &lt;STRONG&gt;New Entity&lt;/STRONG&gt; UI within the simulation window. In this case a parameterized constructor can be called, giving the option of presenting the user with critical configuration choices.&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;Knowing this, I implement two constructors, and a method to populate all the configuration with sensible default values.&lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;        &lt;FONT color=#0000ff&gt;public&lt;/FONT&gt; PursuitCameraEntity()
        {
            SetDefaults();
        }

        &lt;FONT color=#0000ff&gt;public&lt;/FONT&gt; PursuitCameraEntity(&lt;FONT color=#0000ff&gt;string&lt;/FONT&gt; target)
            : &lt;FONT color=#0000ff&gt;base&lt;/FONT&gt;()
        {
            _targetName = target;
            SetDefaults();      
        }
        
        &lt;FONT color=#0000ff&gt;private void &lt;/FONT&gt;SetDefaults()
        {   
            MinDistance = 4;
            MaxDistance = 6;
            Altitude = 2;
            OcclusionThreshold = 0.5f;
        }
&lt;/CODE&gt;
&lt;/PRE&gt;
&lt;H1&gt;Initializing&lt;/H1&gt;
&lt;P&gt;Regardless of how the entity is created, it will be initialized before it is used. I use this as the opportunity to find the target entity, and to validate the camera type.&lt;/P&gt;&lt;PRE&gt;    &lt;CODE&gt;     &lt;FONT color=#0000ff&gt;public override void&lt;/FONT&gt; Initialize(xna.Graphics.&lt;FONT color=#2b91af&gt;GraphicsDevice&lt;/FONT&gt; device, &lt;FONT color=#2b91af&gt;PhysicsEngine&lt;/FONT&gt; physicsEngine)
        {
            &lt;FONT color=#0000ff&gt;base&lt;/FONT&gt;.Initialize(device, physicsEngine);

            if (CameraModel != &lt;FONT color=#2b91af&gt;CameraModelType&lt;/FONT&gt;.FirstPerson)
            {
                CameraModel = &lt;FONT color=#2b91af&gt;CameraModelType&lt;/FONT&gt;.FirstPerson;
            }

            FindTarget();
        }
  
        &lt;FONT color=#0000ff&gt;private void&lt;/FONT&gt; FindTarget()
        {
            &lt;FONT color=#0000ff&gt;if&lt;/FONT&gt; (HasBeenInitialized)
            {
                &lt;FONT color=#0000ff&gt;var&lt;/FONT&gt; query = &lt;FONT color=#0000ff&gt;new&lt;/FONT&gt; &lt;FONT color=#2b91af&gt;VisualEntity&lt;/FONT&gt;();
                query.State.Name = _targetName;

                Activate(
                    &lt;FONT color=#2b91af&gt;Arbiter&lt;/FONT&gt;.Choice(
                        &lt;FONT color=#2b91af&gt;SimulationEngine&lt;/FONT&gt;.GlobalInstancePort.Query(query),
                        success =&amp;gt; Target = success.Entity,
                        &lt;FONT color=#2b91af&gt;CcrServiceBase&lt;/FONT&gt;.EmptyHandler
                    )
                );
            }
        }
        
        &lt;FONT color=#0000ff&gt;public&lt;/FONT&gt; &lt;FONT color=#2b91af&gt;VisualEntity&lt;/FONT&gt; Target;

        &lt;FONT color=#0000ff&gt;void&lt;/FONT&gt; Activate&amp;lt;T&amp;gt;(&lt;FONT color=#0000ff&gt;params&lt;/FONT&gt; T[] tasks)
            &lt;FONT color=#0000ff&gt;where&lt;/FONT&gt; T : &lt;FONT color=#2b91af&gt;ITask&lt;/FONT&gt;
        {
            &lt;FONT color=#2b91af&gt;SimulationEngine&lt;/FONT&gt;.GlobalInstance.Activate(tasks);
        }
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;So, after calling the base &lt;CODE&gt;Initialize()&lt;/CODE&gt; method, I check that the camera is a first person camera type (which simplifies managing the viewing parameters of the camera) and call &lt;CODE&gt;FindTarget()&lt;/CODE&gt;, which allows me to post a query to the SimulationEngine that looks for an entity with the name &lt;CODE&gt;_targetName&lt;/CODE&gt;. If an entity is found then the &lt;CODE&gt;Target&lt;/CODE&gt; field is set appropriately&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Note:&lt;/STRONG&gt; querying the simulation engine is an asynchronous process, so I will need to be careful to check that it has completed successfully before I rely on any result.&lt;/P&gt;
&lt;H1&gt;Tracking the target object&lt;/H1&gt;
&lt;P&gt;The only thing that remains is to implement the tracking logic on each frame. The Update() method of each VisualEntity is called once per frame. So all I need to do is override that method, and implement the same logic as I did in the service implementation.&lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;
        &lt;FONT color=#0000ff&gt;public override void&lt;/FONT&gt; Update(&lt;FONT color=#2b91af&gt;FrameUpdate&lt;/FONT&gt; update)
        {
            &lt;FONT color=#0000ff&gt;if&lt;/FONT&gt; (Target != &lt;FONT color=#0000ff&gt;null&lt;/FONT&gt;)
            {
                &lt;FONT color=#008000&gt;// vector to the camera, used for computing the new position&lt;/FONT&gt;
                &lt;FONT color=#0000ff&gt;var&lt;/FONT&gt; entityToCamera = Location - Target.Position;

                &lt;FONT color=#0000ff&gt;var&lt;/FONT&gt; distance = entityToCamera.Length();

                &lt;FONT color=#0000ff&gt;if&lt;/FONT&gt; (distance &amp;gt; 0.1)
                {
                    &lt;FONT color=#0000ff&gt;float&lt;/FONT&gt; scale = 1;

                    &lt;FONT color=#008000&gt;// scale the vector if the distance is outside the bounds&lt;/FONT&gt;
                    &lt;FONT color=#0000ff&gt;if&lt;/FONT&gt; (distance &amp;gt; MaxDistance)
                    {
                        scale = MaxDistance / distance;
                    }
                    &lt;FONT color=#0000ff&gt;else if&lt;/FONT&gt; (distance &amp;lt; MinDistance)
                    {
                        scale = MinDistance / distance;
                    }

                    &lt;FONT color=#0000ff&gt;var&lt;/FONT&gt; scaled = xna.&lt;FONT color=#2b91af&gt;Vector3&lt;/FONT&gt;.Multiply(entityToCamera, scale);

                    &lt;FONT color=#008000&gt;// set the new camera position, although the altitude will be off.&lt;/FONT&gt;
                    &lt;FONT color=#0000ff&gt;var&lt;/FONT&gt; newCamera = Target.Position + scaled;
                    
                    &lt;FONT color=#008000&gt;// constrain the altitude.&lt;/FONT&gt;
                    newCamera.Y = Altitude;

                    &lt;FONT color=#0000ff&gt;base&lt;/FONT&gt;.SetViewParameters(newCamera, Target.Position);
                }
            }
            &lt;FONT color=#0000ff&gt;base&lt;/FONT&gt;.Update(update);
        }

&lt;/CODE&gt;&lt;/PRE&gt;
&lt;H1&gt;Using the entity&lt;/H1&gt;
&lt;P&gt;That's all the coding needed to implement this as a simulation entity. Now all that remains is to add this entity to a scene. To do this:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Start a simulation manifest of your choice, as before I'm just using &lt;CODE&gt;samples\Config\MobileRobots.P3DX.Simulation.manifest.xml&lt;/CODE&gt;&lt;/LI&gt;
&lt;LI&gt;Put the simulator into &lt;EM&gt;Edit Mode&lt;/EM&gt;, by selecting &lt;STRONG&gt;Edit&lt;/STRONG&gt; from the &lt;STRONG&gt;Mode&lt;/STRONG&gt; menu.&lt;/LI&gt;
&lt;LI&gt;Select &lt;STRONG&gt;New...&lt;/STRONG&gt; from the &lt;STRONG&gt;Entity&lt;/STRONG&gt; menu&lt;/LI&gt;
&lt;LI&gt;In the &lt;STRONG&gt;New Entity&lt;/STRONG&gt; dialog find &lt;EM&gt;PursuitCameraEntity&lt;/EM&gt; in the &lt;STRONG&gt;EntityType&lt;/STRONG&gt; list and select it, click &lt;STRONG&gt;OK&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;When prompted for the target name enter &lt;CODE&gt;P3DXMotorBase&lt;/CODE&gt;, and click &lt;STRONG&gt;OK&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;Set the simulator back to &lt;EM&gt;Run Mode&lt;/EM&gt; (&lt;STRONG&gt;Mode&lt;/STRONG&gt; -&amp;gt; &lt;STRONG&gt;Run&lt;/STRONG&gt;) &lt;/LI&gt;
&lt;LI&gt;Select the new &lt;STRONG&gt;PursuitCamera&lt;/STRONG&gt; from the &lt;STRONG&gt;Cameras&lt;/STRONG&gt; menu.&lt;/LI&gt;
&lt;LI&gt;Drive the robot around and see the camera following it.&lt;/LI&gt;
&lt;LI&gt;From the &lt;STRONG&gt;File&lt;/STRONG&gt; menu, select &lt;STRONG&gt;Save Scene As...&lt;/STRONG&gt; to create a new manifest and scene file that now contain the pursuit camera entity&lt;/LI&gt;&lt;/UL&gt;
&lt;H1&gt;Next steps&lt;/H1&gt;
&lt;P&gt;Only two things really remain at this point 
&lt;OL&gt;
&lt;LI&gt;I'd like to be able to control the entity from a service. This will allow me to dynamically change which object I'm tracking and, by changing the distance, altitude and field of view values, zoom in and out on the target&lt;/LI&gt;
&lt;LI&gt;I still want to do occlusion detection so that the camera can do its best to ensure a clear line of sight to the target entity&lt;/LI&gt;&lt;/OL&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8422940" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/pollrobots/archive/tags/Simulation/default.aspx">Simulation</category><category domain="http://blogs.msdn.com/pollrobots/archive/tags/Entity/default.aspx">Entity</category><category domain="http://blogs.msdn.com/pollrobots/archive/tags/C_2300_/default.aspx">C#</category></item><item><title>Pursuit Camera Service</title><link>http://blogs.msdn.com/pollrobots/archive/2008/04/11/pursuit-camera-service.aspx</link><pubDate>Sat, 12 Apr 2008 05:35:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8383584</guid><dc:creator>PollRobots</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/pollrobots/comments/8383584.aspx</comments><wfw:commentRss>http://blogs.msdn.com/pollrobots/commentrss.aspx?PostID=8383584</wfw:commentRss><description>&lt;H1&gt;The problem &lt;/H1&gt;
&lt;P&gt;Often, when using simulation, it would be convenient to have a camera that automatically tracks a robot (or other entity), so that you can watch what is happening without having to continually adjust the camera. &lt;/P&gt;
&lt;P&gt;This is what I set out to write. The aim of the service is to have a camera that follows an entity at a fixed distance and at a fixed height off the ground plane. In a simple way this can be achieved without writing any code at all. Just adding a camera entity as a child to an existing entity does this. This is how the robot camera in the Pioneer 3DX Simulation works. If you run that manifest &lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas"&gt;(/samples/config/MobileRobots.P3DX.Simulation.manifest.xml&lt;/SPAN&gt;); you can easily edit the attached camera settings to do this. &lt;/P&gt;
&lt;P&gt;Select &lt;STRONG&gt;Mode&lt;/STRONG&gt; -&amp;gt; &lt;STRONG&gt;Edit &lt;/STRONG&gt;from&lt;STRONG&gt; &lt;/STRONG&gt;the Simulation window menu. Then in the entity tree on the top left, expand &lt;STRONG&gt;P3DXMotorBase&lt;/STRONG&gt; and select &lt;STRONG&gt;robocam&lt;/STRONG&gt;. Then in the properties window on the bottom left, in the &lt;STRONG&gt;Misc&lt;/STRONG&gt; group, set the &lt;STRONG&gt;CameraModel&lt;/STRONG&gt; to &lt;STRONG&gt;AttachedChild&lt;/STRONG&gt;. Then set the &lt;STRONG&gt;Position&lt;/STRONG&gt; to 0, 2.5, 5 and the &lt;STRONG&gt;Rotation&lt;/STRONG&gt; to -20, 0, 0. Now selecting &lt;STRONG&gt;Mode&lt;/STRONG&gt; -&amp;gt; &lt;STRONG&gt;Run&lt;/STRONG&gt; from the menu, followed by &lt;STRONG&gt;Camera&lt;/STRONG&gt; -&amp;gt; &lt;STRONG&gt;robocam&lt;/STRONG&gt; will select that camera view as the current window view. Now as you drive the robot around from the &lt;EM&gt;SimpleDashboard&lt;/EM&gt;, it stays in the center of the simulation window. However, the way the camera moves when the robot turns tends to make me a little nauseous, so I figured that I could implement a pursuit camera quite easily, hence this service… &lt;/P&gt;
&lt;P&gt;Another way of illustrating the problem is shown in the following image… &lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;IMG title="Camera Track" style="WIDTH: 381px; HEIGHT: 214px" height=214 alt="Camera Track" src="http://blogs.msdn.com/photos/pollrobots/images/8378266/original.aspx" width=381 mce_src="http://blogs.msdn.com/photos/pollrobots/images/8378266/original.aspx"&gt;&lt;/P&gt;
&lt;P&gt;Here the thicker gray line shows the path that a robot is travelling on; the purple path shows how a fixed, or attached, camera would move; and the red path shows how a simple pursuit camera might move. For both cameras the robot is always centered in the cameras view, but the pursuit camera follows a smooth path, whereas the attached camera's path jumps about as the robot rotates on the spot. &lt;/P&gt;
&lt;H1&gt;Writing the Service &lt;/H1&gt;
&lt;H2&gt;Static Configuration &lt;/H2&gt;
&lt;P&gt;The first thing that I do when writing a new service is decide what is going to be in the service state. To start with this service just needs to know: &lt;/P&gt;
&lt;UL style="MARGIN-LEFT: 38pt"&gt;
&lt;LI&gt;Which entity to follow &lt;/LI&gt;
&lt;LI&gt;The ideal distance of the camera from the entity &lt;/LI&gt;
&lt;LI&gt;The height that the camera should be above the ground plane. &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;The first of these is best handled as a partner, in common with other simulation services. The other two become part of the service state. &lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;    [DataContract]
    &lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;class&lt;/SPAN&gt; PursuitCameraState
    {
        [DataMember, Browsable(&lt;SPAN style="COLOR: blue"&gt;true&lt;/SPAN&gt;), Description(&lt;SPAN style="COLOR: #a31515"&gt;"Distance &lt;/SPAN&gt;&lt;/CODE&gt;&lt;CODE&gt;&lt;SPAN style="COLOR: #a31515"&gt;to 
                  keep the camera from the entity"&lt;/SPAN&gt;)]
        &lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;float&lt;/SPAN&gt; Distance { &lt;SPAN style="COLOR: blue"&gt;get&lt;/SPAN&gt;; &lt;SPAN style="COLOR: blue"&gt;set&lt;/SPAN&gt;; }

        [DataMember, Browsable(&lt;SPAN style="COLOR: blue"&gt;true&lt;/SPAN&gt;), Description(&lt;SPAN style="COLOR: #a31515"&gt;"Height above 
                  the ground plane to keep the camera"&lt;/SPAN&gt;)]
        &lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;float&lt;/SPAN&gt; Altitude { &lt;SPAN style="COLOR: blue"&gt;get&lt;/SPAN&gt;; &lt;SPAN style="COLOR: blue"&gt;set&lt;/SPAN&gt;; }
    }
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;I need to be able to configure these, so I specify an InitialStatePartner &lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;    public class &lt;SPAN style="COLOR: #2b91af"&gt;PursuitCameraService&lt;/SPAN&gt; : &lt;SPAN style="COLOR: #2b91af"&gt;DsspServiceBase
&lt;/SPAN&gt;    {
        [&lt;SPAN style="COLOR: #2b91af"&gt;InitialStatePartner&lt;/SPAN&gt;(Optional = true)]
        private &lt;SPAN style="COLOR: #2b91af"&gt;PursuitCameraState&lt;/SPAN&gt; _state = new &lt;SPAN style="COLOR: #2b91af"&gt;PursuitCameraState&lt;/SPAN&gt;();
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;and, because I declare the initial state partner to be optional, I use some (hopefully) sensible defaults in the service's Start() method &lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;        protected override void Start()
        {
            if (_state == null)
            {
                _state = new &lt;SPAN style="COLOR: #2b91af"&gt;PursuitCameraState&lt;/SPAN&gt;
                {
                    Distance = 5,
                    Altitude = 2
                };
            }
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;H2&gt;Dynamic Configuration &lt;/H2&gt;
&lt;P&gt;In order to function, the service needs to know the entity it is following and the camera which it is moving. The entity will be specified using a partner (which I'll get to in a moment), and for now I'm just going to move the main camera. &lt;/P&gt;
&lt;P&gt;The best way to get access to the entity is to specify its name as a partner and then to subscribe to the simulation engine. My service will then receive notifications when an entity with that name is added to the scene or deleted from the scene. To do this I add the SimulationEngine as a partner (this is covered in &lt;A href="http://msdn2.microsoft.com/en-us/library/bb483077.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/bb483077.aspx"&gt;Simulation Tutorial 1&lt;/A&gt; so I won't describe it here), and subscribe to the simulation engine. &lt;/P&gt;
&lt;P&gt;My Start() method now contains the following… &lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;
        &lt;SPAN style="COLOR: blue"&gt;base&lt;/SPAN&gt;.Start();

        _simPort = sime.&lt;SPAN style="COLOR: #2b91af"&gt;SimulationEngine&lt;/SPAN&gt;.GlobalInstancePort;
        _simPort.Subscribe(ServiceInfo.PartnerList, _simNotify);

        &lt;SPAN style="COLOR: blue"&gt;base&lt;/SPAN&gt;.MainPortInterleave.CombineWith(
            &lt;SPAN style="COLOR: #2b91af"&gt;Arbiter&lt;/SPAN&gt;.Interleave(
                &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;TeardownReceiverGroup&lt;/SPAN&gt;(),
                &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;ExclusiveReceiverGroup&lt;/SPAN&gt;(
                    &lt;SPAN style="COLOR: #2b91af"&gt;Arbiter&lt;/SPAN&gt;.ReceiveWithIterator
    &amp;lt;sime.&lt;SPAN style="COLOR: #2b91af"&gt;InsertSimulationEntity&lt;/SPAN&gt;&amp;gt;(&lt;SPAN style="COLOR: blue"&gt;true&lt;/SPAN&gt;, _simNotify, 
    OnInsertEntity),
                    &lt;SPAN style="COLOR: #2b91af"&gt;Arbiter&lt;/SPAN&gt;.Receive
    &amp;lt;sime.&lt;SPAN style="COLOR: #2b91af"&gt;DeleteSimulationEntity&lt;/SPAN&gt;&amp;gt;(&lt;SPAN style="COLOR: blue"&gt;true&lt;/SPAN&gt;, _simNotify, 
    OnDeleteEntity)
                ),
                &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;ConcurrentReceiverGroup&lt;/SPAN&gt;()
            )
        );
    }
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;…because I'm interested in receiving notifications of when the entity is added to the scene I need to receivers for the appropriate notifications, (in this case InsertSimulationEntity and DeleteSimulationEntity) and I also keep a reference to the simulation engine's global instance port as a convenience. Elsewhere in my service class I have declared the following fields… &lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;        sime.&lt;SPAN style="COLOR: #2b91af"&gt;SimulationEnginePort&lt;/SPAN&gt; _simPort;
        sime.&lt;SPAN style="COLOR: #2b91af"&gt;SimulationEnginePort&lt;/SPAN&gt; _simNotify = 
                &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; sime.&lt;SPAN style="COLOR: #2b91af"&gt;SimulationEnginePort&lt;/SPAN&gt;();
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;I can now keep track of the lifecycle of the entity that I am tracking by implementing OnInsertEntity and OnDeleteEntity as follows &lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;
    sime.&lt;SPAN style="COLOR: #2b91af"&gt;VisualEntity&lt;/SPAN&gt; _entity;
    sime.&lt;SPAN style="COLOR: #2b91af"&gt;CameraEntity&lt;/SPAN&gt; _camera;

    &lt;SPAN style="COLOR: #2b91af"&gt;IEnumerator&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: #2b91af"&gt;ITask&lt;/SPAN&gt;&amp;gt; OnInsertEntity(
        sime.&lt;SPAN style="COLOR: #2b91af"&gt;InsertSimulationEntity&lt;/SPAN&gt; insert)
    {
        _entity = insert.Body;

        &lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; query = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; sime.&lt;SPAN style="COLOR: #2b91af"&gt;VisualEntity&lt;/SPAN&gt;();
        query.State.Name = &lt;SPAN style="COLOR: #a31515"&gt;"MainCamera"&lt;/SPAN&gt;;

        &lt;SPAN style="COLOR: blue"&gt;yield&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;Arbiter&lt;/SPAN&gt;.Choice(
            _simPort.Query(query),
            success =&amp;gt; _camera = success.Entity &lt;SPAN style="COLOR: blue"&gt;as&lt;/SPAN&gt; sime.&lt;SPAN style="COLOR: #2b91af"&gt;CameraEntity&lt;/SPAN&gt;,
            failure =&amp;gt; LogError(&lt;SPAN style="COLOR: #a31515"&gt;"Unable to find camera"&lt;/SPAN&gt;, failure)
         );
    }

    &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; OnDeleteEntity(sime.&lt;SPAN style="COLOR: #2b91af"&gt;DeleteSimulationEntity&lt;/SPAN&gt; delete)
    {
        _entity = &lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt;;
        _camera = &lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt;;
    }
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;OnInsertEntity does two things, firstly it stores the entity in the private member _entity, and then it queries the simulation engine to find the main camera (which is conveniently always called "MainCamera"). OnDeleteEntity merely clears these references. &lt;/P&gt;
&lt;P&gt;I'm using new C# syntax, so where previously I would have had to write &lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;    sime.&lt;SPAN style="COLOR: #2b91af"&gt;VisualEntity&lt;/SPAN&gt; query = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; sime.&lt;SPAN style="COLOR: #2b91af"&gt;VisualEntity&lt;/SPAN&gt;();
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;I now just have &lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;
    &lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; query = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; sime.&lt;SPAN style="COLOR: #2b91af"&gt;VisualEntity&lt;/SPAN&gt;();
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;and where I would have needed &lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;
    &lt;SPAN style="COLOR: blue"&gt;delegate&lt;/SPAN&gt;(sime.&lt;SPAN style="COLOR: #2b91af"&gt;QuerySimulationEntityResponseType&lt;/SPAN&gt; success)
    {
        _camera = success.Entity &lt;SPAN style="COLOR: blue"&gt;as&lt;/SPAN&gt; sime.&lt;SPAN style="COLOR: #2b91af"&gt;CameraEntity&lt;/SPAN&gt;;
    },
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;I can simply have… &lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;    success =&amp;gt; _camera = success.Entity &lt;SPAN style="COLOR: blue"&gt;as&lt;/SPAN&gt; sime.&lt;SPAN style="COLOR: #2b91af"&gt;CameraEntity&lt;/SPAN&gt;,
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;H2&gt;Adjusting the Camera &lt;/H2&gt;
&lt;P&gt;So far so good, but the service doesn't do anything yet! I now need to adjust the camera in keeping with the height and distance constraints specified in the service state. The simplest way to do this is to create a method on the service that is called periodically, ideally once per frame. To make updates in the simulator on a per-frame basis will require me to write an Entity, I'll cover how to do that another time. For now I chose a simple approach that mostly works! &lt;/P&gt;
&lt;P&gt;DSS now has the ability to declare that a service handler should be called periodically, so all I need to do is create a new message type, add it to my service port, and then create a handler in my service. &lt;/P&gt;
&lt;P&gt;The new message type is a Submit with an empty body type… &lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;    [DataContract]
    &lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;class&lt;/SPAN&gt; TickRequest
    {
    }

    &lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;class&lt;/SPAN&gt; Tick : 
        Submit&amp;lt;TickRequest, PortSet&amp;lt;DefaultSubmitResponseType, Fault&amp;gt;&amp;gt;
    {
    }
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;And the handler for this message is where the real work of this service is done… &lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;        [&lt;SPAN style="COLOR: #2b91af"&gt;ServiceHandler&lt;/SPAN&gt;(Interval = 0.025)]
        &lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; OnTick(&lt;SPAN style="COLOR: #2b91af"&gt;Tick&lt;/SPAN&gt; tick)
        {
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;The Interval parameter on the ServiceHandler attribute sets an interval in seconds at which the DSS runtime should call this handler. I chose 40 times per second to be in the same order of speed as the frame rate of the simulator. &lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;
            &lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; (_entity == &lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt; || _camera == &lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt;) 
            { 
                tick.ResponsePort.Post(
                    &lt;SPAN style="COLOR: #2b91af"&gt;DefaultSubmitResponseType&lt;/SPAN&gt;.Instance); 
                &lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt;; 
            }
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;I check that I have references to the entity and the camera, this allows the service to run before the required entity is added to the scene. &lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;
            &lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; entityToCamera = _camera.Location - _entity.Position;
            &lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; distance = entityToCamera.Length();
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;I now just compute the vector from the entity to the camera and find out it's length. &lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;
            &lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; (distance &amp;gt; 0.1)
            {
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;To avoid division by zero, or numerical instability caused by dividing by a very small number, I set an arbitrary threshold (10cm) and don't move the camera if it is very close to the entity. &lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;
                &lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; scaled = xna.&lt;SPAN style="COLOR: #2b91af"&gt;Vector3&lt;/SPAN&gt;.Multiply(entityToCamera, 
                    _state.Distance / distance);
                &lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; newCamera = _entity.Position + scaled;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;this scales the vector from the entity to the camera to give it the length required in the service state. &lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;                newCamera.Y = _state.Altitude;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;I now force the altitude to be correct, this can cause the distance to be either too short or too long, but over a few frames it will settle into place more or less correctly &lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;
                &lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; view = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; sime.&lt;SPAN style="COLOR: #2b91af"&gt;CameraView&lt;/SPAN&gt;
                { 
                    EyePosition = sime.&lt;SPAN style="COLOR: #2b91af"&gt;TypeConversion&lt;/SPAN&gt;.FromXNA(newCamera), 
                    LookAtPoint = sime.&lt;SPAN style="COLOR: #2b91af"&gt;TypeConversion&lt;/SPAN&gt;.FromXNA(_entity.Position)
                }; 
                
               _simPort.Update(view); &lt;/CODE&gt;
&lt;/PRE&gt;
&lt;P&gt;This then just sets the main camera view to point at the current entity position from the newly computed camera position. &lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;            }
            tick.ResponsePort.Post(&lt;SPAN style="COLOR: #2b91af"&gt;DefaultSubmitResponseType&lt;/SPAN&gt;.Instance);
        }
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;The service is now done, now how do I run it… &lt;/P&gt;
&lt;H1&gt;Running the service &lt;/H1&gt;
&lt;P&gt;The easiest way to run this is to use the &lt;STRONG&gt;DSS Manifest Editor&lt;/STRONG&gt;, or dssme (typically pronounced &lt;EM&gt;Dis-Me&lt;/EM&gt;), to create a manifest. After starting dssme, I import a manifest with an interesting simulation world in it (a great place to start is /samples/config/MobileRobots.P3DX.Simulation.manifest.xml) using &lt;STRONG&gt;File&lt;/STRONG&gt; -&amp;gt; &lt;STRONG&gt;Import Manifest&lt;/STRONG&gt;. &lt;/P&gt;
&lt;P&gt;I then add the &lt;EM&gt;SimpleDashboard&lt;/EM&gt; service from the service list on the left, so that I have some means of driving the robot. &lt;/P&gt;
&lt;P&gt;Then I add my new PursuitCamera service and an entry appears in the service list that looks like… &lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;IMG title="Pursuit Camera in DssMe" style="WIDTH: 668px; HEIGHT: 138px" height=138 alt="Pursuit Camera in DssMe" src="http://blogs.msdn.com/photos/pollrobots/images/8383536/original.aspx" width=668 mce_src="http://blogs.msdn.com/photos/pollrobots/images/8383536/original.aspx"&gt;&lt;/P&gt;
&lt;P&gt;I can now drag the &lt;STRONG&gt;SimulationEngine&lt;/STRONG&gt; service onto the &lt;STRONG&gt;SimulationEngine&lt;/STRONG&gt; partner link under the PursuitCamera, and then click on the &lt;STRONG&gt;Entity&lt;/STRONG&gt; partner and the click on the Select button which appears in the properties to select the entity to follow, if I'm using the simulated pioneer manifest, then I select &lt;STRONG&gt;http://localhost/P3DXMotorBase&lt;/STRONG&gt; for the entity. &lt;/P&gt;
&lt;P&gt;Now all I need to do is save and run, and the main camera follows the robot as I drive it around! &lt;/P&gt;
&lt;H1&gt;Next steps &lt;/H1&gt;
&lt;P&gt;I'm not entirely happy with this service as it stands; it has the following problems… &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;It's jerky – updating on a timer doesn't work as well as updating every frame would &lt;/LI&gt;
&lt;LI&gt;It always hijacks the main camera – I want to be able to specify which camera to use &lt;/LI&gt;
&lt;LI&gt;The entity may always be in the center of the visual field, but it isn't always visible – I want to do occlusion detection &lt;/LI&gt;
&lt;LI&gt;I would like to be more sophisticated in how the camera moves when the object is too close – specifying minimum and maximum distances would help &lt;/LI&gt;
&lt;LI&gt;This service doesn't play well with the new record/playback functionality – it needs to detect playback and stop interfering &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;The first of these really requires that this be rewritten to be a new type of camera entity, which also solves the second problem. I'll show how to do that in another post. &lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8383584" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/pollrobots/archive/tags/Simulation/default.aspx">Simulation</category><category domain="http://blogs.msdn.com/pollrobots/archive/tags/Service/default.aspx">Service</category><category domain="http://blogs.msdn.com/pollrobots/archive/tags/C_2300_/default.aspx">C#</category></item><item><title>A new CTP is here!</title><link>http://blogs.msdn.com/pollrobots/archive/2008/04/10/a-new-ctp-is-here.aspx</link><pubDate>Thu, 10 Apr 2008 21:28:28 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8375852</guid><dc:creator>PollRobots</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/pollrobots/comments/8375852.aspx</comments><wfw:commentRss>http://blogs.msdn.com/pollrobots/commentrss.aspx?PostID=8375852</wfw:commentRss><description>&lt;h2&gt;A new CTP - A new name - A new version
&lt;/h2&gt;&lt;p&gt;Microsoft Robotics Developer Studio 2008 CTP April – is now available for download. As always, the downloads page on &lt;a href="http://msdn.microsoft.com/robotics"&gt;Microsoft Robotics&lt;/a&gt; is a great place to start.
&lt;/p&gt;&lt;p&gt;The name has changed; it is now called &lt;strong&gt;Microsoft Robotics Developer Studio&lt;/strong&gt;.
&lt;/p&gt;&lt;p&gt;This also represents a new version, Microsoft RDS 2008 contains far too many exciting new features to list here, but do check out &lt;a href="http://msdn2.microsoft.com/en-us/robotics/cc470040.aspx"&gt;what's new&lt;/a&gt;.
&lt;/p&gt;&lt;h2&gt;A new blog…
&lt;/h2&gt;&lt;p&gt;To introduce myself, I'm Paul Roberts, one of the developers on the Microsoft Robotics team. I'm going to be using this blog to talk about some of what I do on the robotics team; I'll probably pay a little more attention to those features that are close to my heart. I'll also share some services that I have written that might become samples in future releases. 
&lt;/p&gt;&lt;p&gt;When we are getting ready to release a CTP, all the team members test different parts of the release by writing new services and playing with the new features – some of these remain interesting one day exercises, others become samples and tutorials, still others are about to be dissected in detail on this blog.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8375852" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/pollrobots/archive/tags/Microsoft+Robotics/default.aspx">Microsoft Robotics</category></item></channel></rss>