<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Sean's Stuff</title>
	<atom:link href="http://stuff.seans.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://stuff.seans.com</link>
	<description>Various musings on software development and technology.</description>
	<pubDate>Mon, 05 Jan 2009 16:40:50 +0000</pubDate>
	<generator>http://wordpress.org/?v=MU</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<image>
		<url>http://www.gravatar.com/blavatar/d76ce1ec7c63ae00d0599773d2710def?s=96&#038;d=http://s.wordpress.com/i/buttonw-com.png</url>
		<title>Sean's Stuff</title>
		<link>http://stuff.seans.com</link>
	</image>
			<item>
		<title>Using HttpWebRequest for Asynchronous Downloads</title>
		<link>http://stuff.seans.com/2009/01/05/using-httpwebrequest-for-asynchronous-downloads/</link>
		<comments>http://stuff.seans.com/2009/01/05/using-httpwebrequest-for-asynchronous-downloads/#comments</comments>
		<pubDate>Mon, 05 Jan 2009 06:06:51 +0000</pubDate>
		<dc:creator>Sean</dc:creator>
		
		<category><![CDATA[Miscellaneous]]></category>

		<category><![CDATA[Asynchronous Programming]]></category>

		<category><![CDATA[FTP]]></category>

		<category><![CDATA[HTTP]]></category>

		<category><![CDATA[HTTP Download]]></category>

		<guid isPermaLink="false">http://stuff.seans.com/?p=475</guid>
		<description><![CDATA[I&#8217;ve occasionally had a desire to test downloading a file via HTTP or FTP from a server&#8212;either to measure performance, or to stress test the server by kicking off a large number of simultaneous downloads.  Here&#8217;s a little Win Forms client that allows you to download a single file from a server, using either HTTP [...]]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>I&#8217;ve occasionally had a desire to test downloading a file via HTTP or FTP from a server&#8212;either to measure performance, or to stress test the server by kicking off a large number of simultaneous downloads.  Here&#8217;s a little Win Forms client that allows you to download a single file from a server, using either HTTP or FTP.  It shows download progress and displays the average transfer rate, in kb/sec.  It also demonstrates how to use the HttpWebRequest and FtpWebRequest classes in System.Net to do file downloads.</p>
<p>As an added bonus, this app is a nice example of doing a little work on a background thread and then firing callbacks back to the GUI thread to report progress.  This is done using the BeginXxx/EndXxx pattern, as well as using the Invoke method the ensure that GUI updating is done on the correct thread.  I always forget the exact syntax for this, so it&#8217;s nice to have it here to refer to.</p>
<p>The bulk of this code comes directly from the <a href="http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.begingetresponse.aspx">MSDN documentation</a> for the HttpWebRequest.BeginGetResponse method.  I&#8217;ve created a little client app around it, adding some GUI elements to show progress.  I&#8217;ve also extended it to support downloads using FTP.</p>
<p>I include code snippets in this article, but you can download the entire Visual Studio 2008 solution <a href="http://www.seans.com/samples/DownloadStressTest.zip">here</a>.</p>
<p><strong>The End Result</strong></p>
<p>When we&#8217;re done, we&#8217;ll have a little Win Forms app that lets us enter an HTTP or FTP path to a file and then downloads that file.  During the download, we see the progress, as well as the average transfer rate.</p>
<p><img class="alignnone size-full wp-image-482" title="Download Stress Test application" src="http://spsexton.files.wordpress.com/2009/01/01running.jpg?w=501&#038;h=256" alt="Download Stress Test application" width="501" height="256" /></p>
<p>For the moment, the application doesn&#8217;t actually write the file locally.  Instead, it just downloads the entire file, throwing away the data that it downloaded.  The intent is to stress the server and measure the transfer speed&#8212;not to actually get a copy of the file.</p>
<p>If we were to use HTTP and specify an HTML file to download, we&#8217;d basically be doing the same thing that a web browser does&#8212;downloading a web page from the server to the client.  In the example above, I download a 1.9MB Powerpoint file from the PDC conference, just so that we have something a little larger than a web page and can see some progress.</p>
<p><strong>Using FTP Instead of HTTP</strong></p>
<p>My little application does FTP, as well as HTTP.  If you enter an FTP-based URI, rather than an HTTP-based one, we automatically switch to using FTP to download the file.  Before the download can start, however, we need to ask the user for credentials to use to log into the FTP site.</p>
<p><img class="alignnone size-full wp-image-483" title="FTP Credentials" src="http://spsexton.files.wordpress.com/2009/01/02credentials.jpg?w=354&#038;h=221" alt="FTP Credentials" width="354" height="221" /></p>
<p>Once we&#8217;ve gotten the FTP credentials, the download runs in much the same way that the HTTP-based download ran.</p>
<p><img class="alignnone size-full wp-image-484" title="Downloading a file from an FTP server" src="http://spsexton.files.wordpress.com/2009/01/03ftprunning.jpg?w=501&#038;h=256" alt="Downloading a file from an FTP server" width="501" height="256" /></p>
<p>In this case, I&#8217;m downloading an ISO image of the first CD of a Fedora distribution.  Note that the FTP response string starts with &#8220;213&#8243;, which gives file status and represents a successful response from the FTP server.  The second part of the response string is the size of the file, in bytes.  In the case of HTTP, the response was just &#8220;OK&#8221;.</p>
<p><strong>Where Are We?</strong></p>
<p>So what do we really have here?  A little program that downloads a single file without really writing it anywhere.  At this point, we have something that&#8217;s mildly useful for testing a server, since it tells us the transfer rate.  Furthermore, we can launch a bunch of these guys in parallel and download the same file many times in parallel, to stress the server.  (Ideally, the application would let us pick #-of-simultaneous-downloads and just kick them all off, but that&#8217;s an enhancement to be added later).</p>
<p><strong>Diving Into the Source Code</strong></p>
<p>More interesting than what this little program does is how you go about using the <strong>HttpWebRequest </strong>and <strong>FtpWebRequest </strong>classes to do the actual work.</p>
<p>Here&#8217;s a quick look at the C# solution:</p>
<p><img class="alignnone size-full wp-image-486" title="Files in Solution" src="http://spsexton.files.wordpress.com/2009/01/04solution.jpg?w=218&#038;h=206" alt="Files in Solution" width="218" height="206" /></p>
<p>There&#8217;s really not much here&#8212;the main form (<strong>DownloadStressTestForm</strong>), the FTP credentials form (<strong>GetCredentialsForm</strong>) and a little helper class used to pass data around between asynchronous methods.</p>
<p>Most of the code lives in <strong>DownloadStressTestForm.cs</strong>.  Ideally, we&#8217;d split this out into the GUI pieces and the actual plumbing code that does the work of downloading the files.  But this is just a quick-and-dirty project.</p>
<p><strong>Push the Button</strong></p>
<p>Let&#8217;s take a look at the code that fires when you click the <strong>Get File</strong> button.</p>
<pre name="code" class="csharp">

        private void btnGetFile_Click(object sender, EventArgs e)
        {
            try
            {
                lblDownloadComplete.Visible = false;

                WebRequest req = null;
                WebRequestState reqState = null;
                Uri fileURI = new Uri(txtURI.Text);

                if (fileURI.Scheme == Uri.UriSchemeHttp)
                {
                    req = (HttpWebRequest)HttpWebRequest.Create(fileURI);
                    reqState = new HttpWebRequestState(BUFFER_SIZE);
                    reqState.request = req;
                }
                else if (fileURI.Scheme == Uri.UriSchemeFtp)
                {
                    // Get credentials
                    GetCredentialsForm frmCreds = new GetCredentialsForm();
                    DialogResult result = frmCreds.ShowDialog();
                    if (result == DialogResult.OK)
                    {
                        req = (FtpWebRequest)FtpWebRequest.Create(fileURI);
                        req.Credentials = new NetworkCredential(frmCreds.Username, frmCreds.Password);
                        reqState = new FtpWebRequestState(BUFFER_SIZE);

                        // Set FTP-specific stuff
                        ((FtpWebRequest)req).KeepAlive = false;

                        // First thing we do is get file size.  2nd step, done later,
                        // will be to download actual file.
                        ((FtpWebRequest)req).Method = WebRequestMethods.Ftp.GetFileSize;
                        reqState.FTPMethod = WebRequestMethods.Ftp.GetFileSize;

                        reqState.request = req;
                    }
                    else
                        req = null;	// abort

                }
                else
                    MessageBox.Show(&quot;URL must be either http://xxx or ftp://xxxx&quot;);

                if (req != null)
                {
                    reqState.fileURI = fileURI;
                    reqState.respInfoCB = new ResponseInfoDelegate(SetResponseInfo);
                    reqState.progCB = new ProgressDelegate(Progress);
                    reqState.doneCB = new DoneDelegate(Done);
                    reqState.transferStart = DateTime.Now;

                    // Start the asynchronous request.
                    IAsyncResult result =
                      (IAsyncResult)req.BeginGetResponse(new AsyncCallback(RespCallback), reqState);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(string.Format(&quot;EXC in button1_Click(): {0}&quot;, ex.Message));
            }
        }
</pre>
<p>The basic goal here is to create an instance of either the <strong>HttpWebRequest</strong> or <strong>FtpWebRequest</strong> class.  This is done by calling the corresponding <strong>Create</strong> method, and passing it the URI that the user entered.  Note that we use the <strong>Uri </strong>class to figure out if the user is entering an HTTP or an FTP URI.  We create an instance of the base class, <strong>WebRequest</strong>, which we&#8217;ll use to kick everything off.</p>
<p>We also create an instance of a class used to store some state information, either <strong>HttpWebRequestState</strong> or <strong>FtpWebRequestState</strong>.  These classes both derive from <strong>WebRequestState</strong> and are defined in this project, in <strong>WebRequestState.cs</strong>.</p>
<p>The idea of this state object is that we&#8217;ll hand it off to the asynchronous method that we use to do the actual download.  It then will get passed back to the callback that fires when an asynchronous method completes.  Think of it as a little suitcase of stuff that we want to carry around with us and hand off between the asynchronous methods.</p>
<p>Notice that if we&#8217;re doing an FTP transfer, we first pop up the credentials dialog to get the Username and Password from the user.  We then store those credentials in the <strong>FtpWebRequest</strong> object.</p>
<p>There&#8217;s one other difference between HTTP and FTP.  In the case of HTTP, we&#8217;ll fire off a single web request, with a GET command, to download the file.  But for FTP, we actually first send a command to read the file size, followed by the command to actually download the file.  To accomplish this, we set the <strong>Method</strong> property of the <strong>FtpWebRequest</strong> to <strong>WebRequestMethods.Ftp.GetFileSize</strong>.  We don&#8217;t set this property for <strong>HttpWebRequest</strong> because it just defaults to the GET command, which is what we want.</p>
<p>Towards the end of this function, you&#8217;ll see that I&#8217;m loading up the suitcase&#8212;setting the various properties of the <strong>WebRequestState</strong> object.  Along with the URI, we set up some delegates to point back to three callbacks in the <strong>DownloadStressTestForm</strong> class&#8212;<strong>SetResponseInfo</strong>, <strong>Progress</strong>, and <strong>Done</strong>.  These are the callbacks that actually update our user interface&#8212;when things start, during the file transfer, and when the file has finished downloading.</p>
<p>Finally, we call the <strong>BeginGetResponse</strong> method to actually launch the download.  Here, we specify a response callback&#8212;the method that will get called, not when the download has completed, but just when we get the actual HTTP response, or when the FTP command completes.  In the case of HTTP, we first get the response packet and then start reading the actual file using a stream that we get from the response.</p>
<p>What&#8217;s important here is that we push the work into the background, on another thread, as soon as possible.  We don&#8217;t do much work in the button click event handler before calling <strong>BeginGetResponse</strong>.  And this method is asynchronous&#8212;so we return control to the GUI immediately.  From this point on, we will only update the GUI in response to a callback.</p>
<p><strong>Callbacks to Update the GUI</strong></p>
<p>I mentioned the three callbacks above that we use to update the user interface&#8212;<strong>SetResponseInfo</strong>, <strong>Progress</strong>, and <strong>Done</strong>.  Here&#8217;s the declaration of the delegate types:</p>
<pre name="code" class="csharp">

    public delegate void ResponseInfoDelegate(string statusDescr, string contentLength);
    public delegate void ProgressDelegate(int totalBytes, double pctComplete, double transferRate);
    public delegate void DoneDelegate();
</pre>
<p>And here are the bodies of each of these three callbacks, as implemented in <strong>DownloadStressTestForm</strong>.</p>
<pre name="code" class="csharp">

        /// &lt;summary&gt;
        /// Response info callback, called after we get HTTP response header.
        /// Used to set info in GUI about max download size.
        /// &lt;/summary&gt;
        private void SetResponseInfo(string statusDescr, string contentLength)
        {
            if (this.InvokeRequired)
            {
                ResponseInfoDelegate del = new ResponseInfoDelegate(SetResponseInfo);
                this.Invoke(del, new object[] { statusDescr, contentLength });
            }
            else
            {
                lblStatusDescr.Text = statusDescr;
                lblContentLength.Text = contentLength;
            }
        }

        /// &lt;summary&gt;
        /// Progress callback, called when we&#039;ve read another packet of data.
        /// Used to set info in GUI on % complete &amp; transfer rate.
        /// &lt;/summary&gt;
        private void Progress(int totalBytes, double pctComplete, double transferRate)
        {
            if (this.InvokeRequired)
            {
                ProgressDelegate del = new ProgressDelegate(Progress);
                this.Invoke(del, new object[] { totalBytes, pctComplete, transferRate });
            }
            else
            {
                lblBytesRead.Text = totalBytes.ToString();
                progressBar1.Value = (int)pctComplete;
                lblRate.Text = transferRate.ToString(&quot;f0&quot;);
            }
        }

        /// &lt;summary&gt;
        /// GUI-updating callback called when download has completed.
        /// &lt;/summary&gt;
        private void Done()
        {
            if (this.InvokeRequired)
            {
                DoneDelegate del = new DoneDelegate(Done);
                this.Invoke(del, new object[] { });
            }
            else
            {
                progressBar1.Value = 0;
                lblDownloadComplete.Visible = true;
            }
        }
</pre>
<p>This is pretty simple stuff.  To start with, notice the common pattern in each method, where we check <strong>InvokeRequired</strong>.  Remember the primary rule about updating controls in a user interface and asynchronous programming: the controls must be updated by the same thread that created them.  <strong>InvokeRequired</strong> tells us if we&#8217;re on the right thread or not.  If not, we use the <strong>Invoke</strong> method to recursively call ourselves, but on the thread that created the control (the one that owns the window handle).</p>
<p>Make note of this <strong>InvokeRequired</strong> / <strong>Invoke</strong> pattern.  You&#8217;ll use it whenever you&#8217;re doing background work on another thread and then you want to return some information back to the GUI.</p>
<p>The work that these callbacks do is very simple.  <strong>SetResponseInfo</strong> is called when we first get the reponse packet, as we start downloading the file.  We get an indication of the file size, which we write to the GUI.  <strong>Progress</strong> is called for each packet that we download.  We update the labels that indicate # bytes received and average transfer rate, as well as the main progress bar.  <strong>Done</strong> is called when we&#8217;re all done transfering the file.</p>
<p><strong>The Response Callback</strong></p>
<p>Let&#8217;s go back to where we called the <strong>WebRequest.BeginGetResponse</strong> method.  We we called this method, we specified our <strong>RespCallback</strong> as the method to get invoked when the response packet was received.  Here&#8217;s the code:</p>
<pre name="code" class="csharp">

        /// &lt;summary&gt;
        /// Main response callback, invoked once we have first Response packet from
        /// server.  This is where we initiate the actual file transfer, reading from
        /// a stream.
        /// &lt;/summary&gt;
        private static void RespCallback(IAsyncResult asyncResult)
        {
            try
            {
                // Will be either HttpWebRequestState or FtpWebRequestState
                WebRequestState reqState = ((WebRequestState)(asyncResult.AsyncState));
                WebRequest req = reqState.request;
                string statusDescr = &quot;&quot;;
                string contentLength = &quot;&quot;;

                // HTTP
                if (reqState.fileURI.Scheme == Uri.UriSchemeHttp)
                {
                    HttpWebResponse resp = ((HttpWebResponse)(req.EndGetResponse(asyncResult)));
                    reqState.response = resp;
                    statusDescr = resp.StatusDescription;
                    reqState.totalBytes = reqState.response.ContentLength;
                    contentLength = reqState.response.ContentLength.ToString();   // # bytes
                }

                // FTP part 1 - response to GetFileSize command
                else if ((reqState.fileURI.Scheme == Uri.UriSchemeFtp) &amp;&amp;
                         (reqState.FTPMethod == WebRequestMethods.Ftp.GetFileSize))
                {
                    // First FTP command was GetFileSize, so this 1st response is the size of
                    // the file.
                    FtpWebResponse resp = ((FtpWebResponse)(req.EndGetResponse(asyncResult)));
                    statusDescr = resp.StatusDescription;
                    reqState.totalBytes = resp.ContentLength;
                    contentLength = resp.ContentLength.ToString();   // # bytes
                }

                // FTP part 2 - response to DownloadFile command
                else if ((reqState.fileURI.Scheme == Uri.UriSchemeFtp) &amp;&amp;
                         (reqState.FTPMethod == WebRequestMethods.Ftp.DownloadFile))
                {
                    FtpWebResponse resp = ((FtpWebResponse)(req.EndGetResponse(asyncResult)));
                    reqState.response = resp;
                }

                else
                    throw new ApplicationException(&quot;Unexpected URI&quot;);

                // Get this info back to the GUI -- max # bytes, so we can do progress bar
                if (statusDescr != &quot;&quot;)
                    reqState.respInfoCB(statusDescr, contentLength);

                // FTP part 1 done, need to kick off 2nd FTP request to get the actual file
                if ((reqState.fileURI.Scheme == Uri.UriSchemeFtp) &amp;&amp; (reqState.FTPMethod == WebRequestMethods.Ftp.GetFileSize))
                {
                    // Note: Need to create a new FtpWebRequest, because we&#039;re not allowed to change .Method after
                    // we&#039;ve already submitted the earlier request.  I.e. FtpWebRequest not recyclable.
                    // So create a new request, moving everything we need over to it.
                    FtpWebRequest req2 = (FtpWebRequest)FtpWebRequest.Create(reqState.fileURI);
                    req2.Credentials = req.Credentials;
                    req2.UseBinary = true;
                    req2.KeepAlive = true;
                    req2.Method = WebRequestMethods.Ftp.DownloadFile;

                    reqState.request = req2;
                    reqState.FTPMethod = WebRequestMethods.Ftp.DownloadFile;

                    // Start the asynchronous request, which will call back into this same method
                    IAsyncResult result =
                      (IAsyncResult)req2.BeginGetResponse(new AsyncCallback(RespCallback), reqState);
                }
                else    // HTTP or FTP part 2 -- we&#039;re ready for the actual file download
                {
                    // Set up a stream, for reading response data into it
                    Stream responseStream = reqState.response.GetResponseStream();
                    reqState.streamResponse = responseStream;

                    // Begin reading contents of the response data
                    IAsyncResult ar = responseStream.BeginRead(reqState.bufferRead, 0, BUFFER_SIZE, new AsyncCallback(ReadCallback), reqState);
                }

                return;
            }
            catch (Exception ex)
            {
                MessageBox.Show(string.Format(&quot;EXC in RespCallback(): {0}&quot;, ex.Message));
            }
        }
</pre>
<p>The first thing that we do in this method is to open our suitcase&#8211;our <strong>WebRequestState</strong> object, which comes back in the <strong>AsyncState</strong> property of the <strong>IAsyncResult</strong>.</p>
<p>The other main thing that we do in this method is to get the actual <strong>WebResponse</strong> object.  This contains the information that we actually got back from the server.  We do this by calling the <strong>EndGetResponse</strong> method.</p>
<p>Notice the standard <strong>Begin</strong>/<strong>End</strong> pattern for asynchronous programming here.  We could have done all of this synchronously, by calling <strong>GetResponse</strong> on the original <strong>HttpWebRequest</strong> (or <strong>FtpWebRequest</strong> object).  <strong>GetResponse </strong>would have returned an <strong>HttpWebResponse</strong> (or <strong>FtpWebResponse</strong> object).  Instead, we call <strong>BeginGetResponse</strong> to launch the asynchronous method and then call <strong>EndGetResponse</strong> in the callback to get the actual result&#8212;the <strong>WebResponse</strong> object.</p>
<p>At this point, the first thing that we want from the response packet is an indication of the length of the file that we&#8217;re downloading.  We get that from the <strong>ContentLength</strong> property.</p>
<p>It&#8217;s also at this point that we call the <strong>ResponseInfo</strong> delegate, passing it the status string and content length, to update the GUI.  (Using the <strong>respInfoCB</strong> field in the <strong>WebRequestState</strong> object).</p>
<p>Let&#8217;s ignore FTP for the moment and look at the final main thing that we do in this method&#8212;get a stream object and kick off a read of the first packet.  We get the stream from that <strong>WebReponse</strong> object and then go asynchronous again by calling the <strong>BeginRead</strong> method.  Are you seeing a pattern yet?  Again, if we wanted to do everything synchronously, we could just set up a loop here and call the stream&#8217;s <strong>Read</strong> method to read each buffer of data.  But instead, we fire up an asynchronous read, specifying our method that should be called when we get the first packet/buffer of data&#8212;<strong>ReadCallback</strong>.</p>
<p><strong>FTP Download, Step 2</strong></p>
<p>Let&#8217;s go back to how we&#8217;re doing FTP.  Remember that we set the <strong>FtpWebRequest.Method</strong> property to <strong>GetFileSize</strong>.  And in <strong>ReadCallback</strong>, if we see that we just did that first command, we send the file size back to the GUI.  And then we&#8217;re ready to launch the 2nd FTP command, which is <strong>DownloadFile</strong>.  We do this by creating a 2nd <strong>FtpWebRequest</strong> and calling the <strong>BeginGetResponse</strong> method again.  And once again, when the asynchronous method completes, we&#8217;ll get control back in <strong>ReadCallback</strong>.  We don&#8217;t risk recursing indefinitely because we store an indication of which command we&#8217;re doing in our suitcase&#8212;in <strong>WebRequestState.FTPMethod</strong>.</p>
<p><strong>Gettin&#8217; the Data</strong></p>
<p>Finally, let&#8217;s take a look at the code where we actually get a chunk of data from the server.  First, a quick note about buffer size.  Notice that when I called <strong>BeginRead</strong>, I specified a buffer size using the <strong>BUFFER_SIZE</strong> constant.  For the record, I&#8217;m using a value of 1448 here, which is based on the size of a typical TCP packet (packet size less some header info).  We could really use any value here that we liked&#8212;it just seemed reasonable to ask for the data a packet at a time.</p>
<p>Here&#8217;s the code for our read callback, which first fires when the first packet is received, after calling <strong>BeginRead</strong>.</p>
<pre name="code" class="csharp">

        /// &lt;summary&gt;
        /// Main callback invoked in response to the Stream.BeginRead method, when we have some data.
        /// &lt;/summary&gt;
        private static void ReadCallback(IAsyncResult asyncResult)
        {
            try
            {
                // Will be either HttpWebRequestState or FtpWebRequestState
                WebRequestState reqState = ((WebRequestState)(asyncResult.AsyncState));

                Stream responseStream = reqState.streamResponse;

                // Get results of read operation
                int bytesRead = responseStream.EndRead(asyncResult);

                // Got some data, need to read more
                if (bytesRead &gt; 0)
                {
                    // Report some progress, including total # bytes read, % complete, and transfer rate
                    reqState.bytesRead += bytesRead;
                    double pctComplete = ((double)reqState.bytesRead / (double)reqState.totalBytes) * 100.0f;

                    // Note: bytesRead/totalMS is in bytes/ms.  Convert to kb/sec.
                    TimeSpan totalTime = DateTime.Now - reqState.transferStart;
                    double kbPerSec = (reqState.bytesRead * 1000.0f) / (totalTime.TotalMilliseconds * 1024.0f);

                    reqState.progCB(reqState.bytesRead, pctComplete, kbPerSec);

                    // Kick off another read
                    IAsyncResult ar = responseStream.BeginRead(reqState.bufferRead, 0, BUFFER_SIZE, new AsyncCallback(ReadCallback), reqState);
                    return;
                }

                // EndRead returned 0, so no more data to be read
                else
                {
                    responseStream.Close();
                    reqState.response.Close();
                    reqState.doneCB();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(string.Format(&quot;EXC in ReadCallback(): {0}&quot;, ex.Message));
            }
        }
</pre>
<p>As I&#8217;m so fond of saying, this is pretty simple stuff.  Once again, we make use of recursion, because we&#8217;re asynchronously reading a packet at a time.  We get the stream object out of our suitcase and then call <strong>EndRead</strong> to get an indication of how many bytes were read.  This is the indicator that will tell us when we&#8217;re done reading the data&#8212;in which case # bytes read will be 0.</p>
<p>If we&#8217;re all done reading the data, we close down our stream and <strong>WebResponse</strong> object, before calling our final GUI callback to tell the GUI that we&#8217;re done.</p>
<p>But if we did read some data, we first call our progress callback to tell the GUI that we got another packet and then we fire off another <strong>BeginRead</strong>.  (Which will, of course, lead to our landing back in the <strong>ReadCallback</strong> method when the next packet completes).</p>
<p>You can see that we&#8217;re passing back some basic info to the GUI&#8212;total # bytes read, the % complete, and the calculated average transfer rate, in KB per second.</p>
<p>If we actually cared about the data itself, we could find it in our suitcase&#8212;in <strong>WebRequestState.bufferRead</strong>.  This is just a byte array that we specified when we called <strong>BeginRead</strong>.  In the case of this application, we don&#8217;t care about the actual data, so we don&#8217;t do anything with it.</p>
<p><strong>Opening the Suitcase</strong></p>
<p>We&#8217;ve looked at basically all the code, except for the implementation of the <strong>WebRequestState </strong>class that we&#8217;ve been using as our &#8220;suitcase&#8221;.  Here&#8217;s the base class:</p>
<pre name="code" class="csharp">

    /// &lt;summary&gt;
    /// Base class for state object that gets passed around amongst async methods
    /// when doing async web request/response for data transfer.  We store basic
    /// things that track current state of a download, including # bytes transfered,
    /// as well as some async callbacks that will get invoked at various points.
    /// &lt;/summary&gt;
    abstract public class WebRequestState
    {
        public int bytesRead;           // # bytes read during current transfer
        public long totalBytes;            // Total bytes to read
        public double progIncrement;    // delta % for each buffer read
        public Stream streamResponse;    // Stream to read from
        public byte[] bufferRead;        // Buffer to read data into
        public Uri fileURI;                // Uri of object being downloaded
        public string FTPMethod;        // What was the previous FTP command?  (e.g. get file size vs. download)
        public DateTime transferStart;  // Used for tracking xfr rate

        // Callbacks for response packet info &amp; progress
        public ResponseInfoDelegate respInfoCB;
        public ProgressDelegate progCB;
        public DoneDelegate doneCB;

        private WebRequest _request;
        public virtual WebRequest request
        {
            get { return null; }
            set { _request = value; }
        }

        private WebResponse _response;
        public virtual WebResponse response
        {
            get { return null; }
            set { _response = value; }
        }

        public WebRequestState(int buffSize)
        {
            bytesRead = 0;
            bufferRead = new byte[buffSize];
            streamResponse = null;
        }
    }
</pre>
<p>This is just all of the stuff that we wanted to pass around between our asynchronous methods.  You&#8217;ll see our three delegates, for calling back to the GUI.  And you&#8217;ll also see where we store our <strong>WebRequest</strong> and <strong>WebResponse </strong>objects.</p>
<p>The final thing to look at is the code, also in <strong>WebRequestState.cs</strong>, for the two derived classes&#8212;<strong>HttpWebRequestState</strong> and <strong>FtpWebRequestState</strong>.</p>
<pre name="code" class="csharp">

    /// &lt;summary&gt;
    /// State object for HTTP transfers
    /// &lt;/summary&gt;
    public class HttpWebRequestState : WebRequestState
    {
        private HttpWebRequest _request;
        public override WebRequest request
        {
            get
            {
                return _request;
            }
            set
            {
                _request = (HttpWebRequest)value;
            }
        }

        private HttpWebResponse _response;
        public override WebResponse response
        {
            get
            {
                return _response;
            }
            set
            {
                _response = (HttpWebResponse)value;
            }
        }

        public HttpWebRequestState(int buffSize) : base(buffSize) { }
    }

    /// &lt;summary&gt;
    /// State object for FTP transfers
    /// &lt;/summary&gt;
    public class FtpWebRequestState : WebRequestState
    {
        private FtpWebRequest _request;
        public override WebRequest request
        {
            get
            {
                return _request;
            }
            set
            {
                _request = (FtpWebRequest)value;
            }
        }

        private FtpWebResponse _response;
        public override WebResponse response
        {
            get
            {
                return _response;
            }
            set
            {
                _response = (FtpWebResponse)value;
            }
        }

        public FtpWebRequestState(int buffSize) : base(buffSize) { }
    }
</pre>
<p>The whole point of these classes is to allow us to override the <strong>request</strong> and <strong>response</strong> fields in the base class with strong-typed instances&#8212;e.g. <strong>HttpWebRequest</strong> and <strong>HttpWebResponse</strong>.</p>
<p><strong>Wrapping Up</strong></p>
<p>That&#8217;s about it&#8212;that&#8217;s really all that&#8217;s required to implement a very simple HTTP or FTP client application, using the <strong>HttpWebRequest</strong> and <strong>FtpWebRequest</strong> classes in <strong>System.Net</strong>.</p>
<p>This is still a pretty crude application and there are a number of obvious next steps that we could take if we wanted to improve it:</p>
<ul>
<li>Allow user to pick # downloads and kick off simultaneous downloads, each with their own progress bar</li>
<li>Prevent clicking <strong>Get File</strong> button if a download is already in progress.  (Try it&#8212;you do actually get a 2nd download, but the progress bar goes whacky trying to report on both at the same time).</li>
<li>Add a timer so that we can recover if a transfer times out</li>
<li>Allow the user to actually store the data to a local file</li>
<li>Log the results somewhere, especially if we launched multiple downloads</li>
</ul>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/spsexton.wordpress.com/475/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/spsexton.wordpress.com/475/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/spsexton.wordpress.com/475/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/spsexton.wordpress.com/475/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/spsexton.wordpress.com/475/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/spsexton.wordpress.com/475/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/spsexton.wordpress.com/475/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/spsexton.wordpress.com/475/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/spsexton.wordpress.com/475/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/spsexton.wordpress.com/475/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=stuff.seans.com&blog=4003566&post=475&subd=spsexton&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://stuff.seans.com/2009/01/05/using-httpwebrequest-for-asynchronous-downloads/feed/</wfw:commentRss>
	
		<media:content url="http://www.gravatar.com/avatar/8922e4d5254d602ba3ed32dd073b5a4e?s=96&#38;d=identicon" medium="image">
			<media:title type="html">spsexton</media:title>
		</media:content>

		<media:content url="http://spsexton.files.wordpress.com/2009/01/01running.jpg" medium="image">
			<media:title type="html">Download Stress Test application</media:title>
		</media:content>

		<media:content url="http://spsexton.files.wordpress.com/2009/01/02credentials.jpg" medium="image">
			<media:title type="html">FTP Credentials</media:title>
		</media:content>

		<media:content url="http://spsexton.files.wordpress.com/2009/01/03ftprunning.jpg" medium="image">
			<media:title type="html">Downloading a file from an FTP server</media:title>
		</media:content>

		<media:content url="http://spsexton.files.wordpress.com/2009/01/04solution.jpg" medium="image">
			<media:title type="html">Files in Solution</media:title>
		</media:content>
	</item>
		<item>
		<title>Windows 7 Install Screens on PhotoZoom</title>
		<link>http://stuff.seans.com/2008/11/17/windows-7-install-screens-on-photozoom/</link>
		<comments>http://stuff.seans.com/2008/11/17/windows-7-install-screens-on-photozoom/#comments</comments>
		<pubDate>Mon, 17 Nov 2008 18:52:22 +0000</pubDate>
		<dc:creator>Sean</dc:creator>
		
		<category><![CDATA[Windows 7]]></category>

		<category><![CDATA[Deep Zoom]]></category>

		<category><![CDATA[DeepZoom]]></category>

		<category><![CDATA[Windows 7 Install]]></category>

		<guid isPermaLink="false">http://spsexton.wordpress.com/?p=468</guid>
		<description><![CDATA[I just created my first Deep Zoom Composer project.  I added all of my Windows 7 install screenshots to a Deep Zoom project and then simply published them on Photo Zoom.  This was surprisingly easy&#8211;no coding required.  To zoom around in this set of images, click here.

&#160;&#160;&#160;&#160;&#160;&#160;     ]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>I just created my first Deep Zoom Composer project.  I added all of my Windows 7 install screenshots to a Deep Zoom project and then simply published them on Photo Zoom.  This was surprisingly easy&#8211;no coding required.  To zoom around in this set of images, click <a href="http://photozoom.mslivelabs.com/album.aspx?alias=spsexton&amp;album=2">here</a>.</p>
<p><a href="http://photozoom.mslivelabs.com/album.aspx?alias=spsexton&amp;album=2"><img class="alignnone size-full wp-image-469" title="win7installall" src="http://spsexton.files.wordpress.com/2008/11/win7installall.jpg?w=901&#038;h=675" alt="win7installall" width="901" height="675" /></a></p>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/spsexton.wordpress.com/468/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/spsexton.wordpress.com/468/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/spsexton.wordpress.com/468/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/spsexton.wordpress.com/468/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/spsexton.wordpress.com/468/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/spsexton.wordpress.com/468/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/spsexton.wordpress.com/468/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/spsexton.wordpress.com/468/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/spsexton.wordpress.com/468/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/spsexton.wordpress.com/468/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=stuff.seans.com&blog=4003566&post=468&subd=spsexton&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://stuff.seans.com/2008/11/17/windows-7-install-screens-on-photozoom/feed/</wfw:commentRss>
	
		<media:content url="http://www.gravatar.com/avatar/8922e4d5254d602ba3ed32dd073b5a4e?s=96&#38;d=identicon" medium="image">
			<media:title type="html">spsexton</media:title>
		</media:content>

		<media:content url="http://spsexton.files.wordpress.com/2008/11/win7installall.jpg" medium="image">
			<media:title type="html">win7installall</media:title>
		</media:content>
	</item>
		<item>
		<title>A Recipe for Green-Field Software Development</title>
		<link>http://stuff.seans.com/2008/11/15/a-recipe-for-green-field-software-development/</link>
		<comments>http://stuff.seans.com/2008/11/15/a-recipe-for-green-field-software-development/#comments</comments>
		<pubDate>Sat, 15 Nov 2008 15:22:39 +0000</pubDate>
		<dc:creator>Sean</dc:creator>
		
		<category><![CDATA[Miscellaneous]]></category>

		<category><![CDATA[Software development]]></category>

		<category><![CDATA[Software development process]]></category>

		<category><![CDATA[Software lifecycle]]></category>

		<category><![CDATA[Agile methods]]></category>

		<category><![CDATA[Rationa Unified Process]]></category>

		<category><![CDATA[Four Steps to the Epiphany]]></category>

		<category><![CDATA[ISV]]></category>

		<category><![CDATA[Requirements]]></category>

		<category><![CDATA[Inception]]></category>

		<category><![CDATA[Customers]]></category>

		<category><![CDATA[Software Entrepreneur]]></category>

		<category><![CDATA[Product development]]></category>

		<category><![CDATA[Customer development]]></category>

		<category><![CDATA[RUP]]></category>

		<category><![CDATA[Use cases]]></category>

		<category><![CDATA[Software iterations]]></category>

		<category><![CDATA[Customer discovery]]></category>

		<category><![CDATA[Software process]]></category>

		<guid isPermaLink="false">http://spsexton.wordpress.com/?p=441</guid>
		<description><![CDATA[Developing Your Product and Your Customers in Parallel
In my 9-5 life, I’ve been a member of a software development team since 1985.  That’s 23 years as a software developer&#8212;ouch!
Like many developers who have been around for a few years, at least some of my grey hair can be attributed to having worked on hellish projects, [...]]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><em>Developing Your Product and Your Customers in Parallel</em></p>
<p>In my 9-5 life, I’ve been a member of a software development team since 1985.  That’s 23 years as a software developer&#8212;ouch!</p>
<p>Like many developers who have been around for a few years, at least some of my grey hair can be attributed to having worked on hellish projects, or on projects that failed outright.  Over the years, I’ve gradually added to my mental list of “worst practices”&#8212;things that tend to lead to project failure, or at least hide a failing project until it’s too late to turn it into a successful one.</p>
<p>It’s much easier to compile a list of worst practices than it is to pick some “perfect” development process.  But worst practices can lead to best practices simply by avoiding the bad practices.  At a minimum, we should at least avoid making the same mistakes over and over again.</p>
<p>If I had to pick a single worst practice (there are many), it would be this:</p>
<p style="padding-left:30px;">Not building the product that the customer really needed</p>
<p>This happens all of the time.  We (the developers) build a product that is bug-free, efficient, scalable, and does exactly what we intended it to do.  We even occasionally get the work done in something close to the amount of time that we said it would take.</p>
<p>But our well-built software still fails&#8212;for a variety of reasons.</p>
<ul>
<li>It’s too hard to use</li>
<li>Users are unable to use it efficiently/effectively</li>
<li>It’s missing one or more critical features</li>
<li>Users don’t have a need for the software in the first place</li>
<li>It’s too expensive, given what it does</li>
</ul>
<p>In order to be “successful”, software has to meet a critical need that the user has.  Good software solves a pressing problem.  Great software does so in a way that seems natural to the users.</p>
<p>So what do I mean when I talk about software “failure”?  Simply put, “failed” software is: software that doesn’t get used.</p>
<p>What are the consequences of failure?  For internal software projects, it means wasted time and energy that could have been spent on things that the organization <strong>does </strong>need.  For consulting houses, it means possibly not getting hired back by the client, or seeing your reputation diminished.  For ISVs developing software/services to sell, it means lost revenue or even bankruptcy.</p>
<p>For developers, failure means knowing that you’ve wasted your time, intellect and energy on something that no one is going to use.  That sucks.</p>
<p>Our goal then as developers is to build great software.  We want to see users working with our stuff, to see it making their lives better, and to see them excited about it.  That’s the true Holy Grail that many of us work towards.</p>
<p><strong>The Remedy</strong></p>
<p>So how do we develop great software?  We can’t all be Steve Jobs, or hire him into our organization.  So without brilliant insight, how do we figure out what the users truly need?</p>
<p>To understand what users need&#8212;truly, madly, deeply&#8212;we need to think beyond developing <strong>products </strong>and start thinking about developing an understanding of our <strong>users</strong>.</p>
<p>This focus on a Customer Development Process, rather than a Product Development Process, is the point of the book <em><a href="http://www.amazon.com/Four-Steps-Epiphany-Steven-Blank/dp/0976470705/ref=pd_bbs_sr_1?ie=UTF8&amp;s=books&amp;qid=1226760535&amp;sr=8-1">The Four Steps to the Epiphany</a></em>, by Steven Gary Blank.</p>
<p>Blank’s main thesis is that we should work towards an understanding of our customers and their needs much earlier in the development lifecycle.  We need to fully understand what customers need and whether we can sell them our product <strong>before </strong>we go too far down the path of building that product.</p>
<p>Blank proposes a very detailed <em>Customer Development Process </em>and talks a little bit about when it should occur, relative to the typical phases of a <em>Product Development Process</em>.  This is a little tricky.  If we wait too long to learn about our customers, we risk building the wrong product.  But if we talk to them too early, before we’ve had time to think a little bit about our vision, we’re not really innovating, but just trying to build what they tell us to build.  That also can lead to failure.</p>
<p><strong>My Take on the Product Development Process</strong></p>
<p>Having worked as a software developer for so many years, I’ve seen lots of different software lifecycles.  In my first job, with Control Data Corp in Bloomington, MN, we were a Dept of Defense shop and rigidly followed <a href="http://en.wikipedia.org/wiki/DOD-STD-2167A">DOD-STD-2167A</a>&#8212;a very rigidly-defined classic waterfall process.</p>
<p>I’ve also done my share of agile development, working in groups that used various <a href="http://en.wikipedia.org/wiki/Agile_development">agile methods</a>.</p>
<p>My main takeaway on software process is that it’s important to develop <strong>iteratively</strong>.  For me, that’s the most critically important piece of the agile movement.  Many of the other techniques, like pair programming and test driven development might be important, but don’t seem quite as critical as being able to build your product iteratively.  <strong>Short iterations allow agility</strong>.</p>
<p>For me, one book that really made a lot of sense in laying out a framework for an iterative lifecycle was <a href="http://www.amazon.com/Rational-Unified-Process-Made-Easy/dp/0321166094/ref=pd_bbs_sr_1?ie=UTF8&amp;s=books&amp;qid=1226514580&amp;sr=8-1"><em>The Rational Unified Process Made Easy</em></a>, by Per Kroll.</p>
<p>For a lot of people, when they think about RUP (Rational Unified Process), they think: heavyweight and lots of modeling/diagramming.  But Kroll explains that RUP doesn’t necessarily mean heavy.  He refers to the number of artifacts that you’re required to produce as your level of ceremony.  And he describes RUP as:</p>
<p style="padding-left:30px;"><em>An <strong>iterative </strong>approach with an adaptable level of ceremony</em></p>
<p>Again, iterative is the important part.  An iterative approach with very little ceremony would basically be an agile methodology.  But sometimes you work on projects that require a bit more ceremony—some project tracking, etc.  On these projects, you can still be iterative, but with more ceremony.  Here’s a picture:</p>
<p><a href="http://spsexton.files.wordpress.com/2008/11/rupmap.gif"><img class="alignnone size-full wp-image-442" title="rupmap" src="http://spsexton.files.wordpress.com/2008/11/rupmap.gif?w=500&#038;h=365" alt="rupmap" width="500" height="365" /></a></p>
<p>RUP talks about general phases of the lifecycle being: Inception, Elaboration, Construction and Transition.  But Kroll is quick to point out that this does <strong>not </strong>just map to the classic waterfall model.  (Requirements, Analysis/Design, Implementation, Testing).  Rather, you’d typically perform some of each of the classic waterfall activities during each iteration of RUP.  You’d likely be doing a lot more requirements-gathering in your Inception phases, but you’d also be doing some implementation.  And you’d spend a lot of time writing code during Construction phases, but you might also still be tweaking some requirements.</p>
<p>Here’s a nice picture of how RUP typically plays out.  Again, note that the idea of iterations is important:</p>
<p><a href="http://spsexton.files.wordpress.com/2008/11/rupphases.gif"><img class="alignnone size-full wp-image-443" title="rupphases" src="http://spsexton.files.wordpress.com/2008/11/rupphases.gif?w=500&#038;h=345" alt="rupphases" width="500" height="345" /></a></p>
<p>Personally, I like this view of the development lifecycle a lot.  This model is how I think about software development.  Work in an iterative fashion, but be aware of what main phase you’re in and adjust your activities accordingly.</p>
<p>Over the years, I’ve taken lots of notes to answer the question, “what activities should I be doing at each step”?  Kroll has a lot of good information in his book, but I’ve borrowed liberally from other sources.  What I ended up with was a fairly detailed “a la carte” list of activities that you might engage in across the lifecycle.</p>
<p>I say “a la carte” because every project will not engage in every step.  But I think it’s a nice master list to draw from.  And I think that I have the activities listed in a pretty reasonable order.</p>
<p>So here’s my list of high-level activities for the <strong>Product Development Lifecycle</strong>.  (See below for more detail for each activity):</p>
<ul>
<li>Vision</li>
<li>Initial Requirements Gathering  (Inception)</li>
<li>GUI Conceptualizing</li>
<li>Identify Candidate Architecture</li>
<li>Define Non-Functional Tasks</li>
<li>Define Iterations  (Project Planning)</li>
<li>Write Development Plan</li>
<li>Execute Inception iterations</li>
<li>Write Business Plan</li>
<li>Write Test Plan</li>
<li>Write Deployment Plan</li>
<li>Execute Construction Iterations</li>
<li>Initiate Test Plan</li>
<li>Deploy Alpha Release</li>
<li>Write Customer Support Plan</li>
<li>Execute Deployment Iteration</li>
<li>Deploy Beta Release</li>
<li>Launch Product</li>
<li>Begin Planning Next Release</li>
</ul>
<p><strong>The Customer Development Process</strong></p>
<p>I love the idea of the Customer Development Process, as Blank presents it in <a href="http://www.amazon.com/Four-Steps-Epiphany-Steven-Blank/dp/0976470705"><em>The Four Steps to the Epiphany</em></a>.  He talks about discovering who your customers are, figuring out what they need, and then testing your hypotheses.  In other words&#8212;<em>iterate not just on the product, but also on your model of who the customers are</em>.  This includes not just an understanding of the customers and their needs, but also gets into the actual selling proposition and marketing of your product.</p>
<p>Here are the top-level activities in Blank’s customer development process:</p>
<ul>
<li>Customer Discovery</li>
<li>Customer Validation</li>
<li>Customer Creation</li>
<li>Company Building</li>
</ul>
<p><strong>Lining Things Up</strong></p>
<p>The trick is to figure out how the <em>Product Development Process </em>and the <em>Customer Development Process </em>relate to each other.  If you listed out the various phases of each process side by side, how would they line up?  At what point in your product development process should you start the customer development process?  Or should it be the other way around?</p>
<p>Here’s a first stab at lining the two processes up.  My goal was to come up with a high-level roadmap for doing new (green field) development, which would cover developing both the product and the customers.</p>
<table style="width:100%;" border="0">
<tbody>
<tr>
<td><strong>Product Development Process<br />
</strong></td>
<td><strong>Customer Development Process<br />
</strong></td>
</tr>
<tr>
<td></td>
<td></td>
</tr>
<tr>
<td>Vision</td>
<td></td>
</tr>
<tr>
<td>Initial Requirements Gathering</td>
<td></td>
</tr>
<tr>
<td>GUI Conceptualizing</td>
<td></td>
</tr>
<tr>
<td>Identify Candidate Architecture</td>
<td></td>
</tr>
<tr>
<td>Define Non-Functional Tasks</td>
<td></td>
</tr>
<tr>
<td>Define Iterations (Project Planning)</td>
<td></td>
</tr>
<tr>
<td>Write Development Plan</td>
<td></td>
</tr>
<tr>
<td>Execute Inception Iterations  <strong>&gt;&gt;</strong></td>
<td>Customer Discovery</td>
</tr>
<tr>
<td>Write Business Plan</td>
<td></td>
</tr>
<tr>
<td>Write Test Plan</td>
<td></td>
</tr>
<tr>
<td>Write Deployment Plan</td>
<td></td>
</tr>
<tr>
<td>Execute Construction Iterations  <strong>&gt;&gt;</strong></td>
<td>Customer Validation</td>
</tr>
<tr>
<td>Initiate Test Plan</td>
<td></td>
</tr>
<tr>
<td>Deploy Alpha Release  <strong>&gt;&gt;</strong></td>
<td>Customer Creation</td>
</tr>
<tr>
<td>Write Customer Support Plan</td>
<td></td>
</tr>
<tr>
<td>Execute Deployment Iteration</td>
<td></td>
</tr>
<tr>
<td>Deploy Beta Release</td>
<td></td>
</tr>
<tr>
<td>Launch Product</td>
<td></td>
</tr>
<tr>
<td>Begin Planning Next Release  <strong>&gt;&gt;</strong></td>
<td>Company Building</td>
</tr>
<tr>
<td>.</td>
<td></td>
</tr>
</tbody>
</table>
<p><strong>Should I Keep Reading?</strong></p>
<p>The rest of this post expands on each of the activities in the table above, listing details of what happens during each phase.  This is the outline that I use when I’m trying to figure out “what to do next”.</p>
<p>Note again&#8212;this process is very much geared towards green-field development, and in a market where you are developing a product or service to sell to end-users.</p>
<p><strong>Product Development Process&#8212;Details</strong></p>
<p>Here’s the detailed breakdown of the steps involved in the <strong>Product Development Process</strong>.  Much of this content comes from the books I list at the end of the article, primarily <a href="http://www.amazon.com/Rational-Unified-Process-Made-Easy/dp/0321166094/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1226760857&amp;sr=1-1"><em>The Rational Unified Process Made Easy</em></a> and <a href="http://www.amazon.com/First-Software-Development-Brain-Friendly-Guides/dp/0596527357/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1226760891&amp;sr=1-1"><em>Head First Software Development</em></a>.  But a lot of it is just my own concept of what you typically do during each phase.</p>
<p>Note that iterations occur in the Inception and Construction phases.</p>
<p><span style="text-decoration:underline;">Vision</span></p>
<ul>
<li>Do a short description of a handful of possible products
<ul>
<li>For each, describe:
<ul>
<li>Market or market segment  (which group of users, short description)
<ul>
<li>What is the problem that they experience</li>
<li>How painful to the users?  What workarounds are in place?</li>
</ul>
</li>
<li>Short description of product that might help them solve this problem</li>
<li>Short feature list (&lt;10 items, single sentence)</li>
<li>How does this product specifically solve the customer&#8217;s problem?</li>
</ul>
</li>
</ul>
</li>
<li>Expand on top one or two possible products.<br />
<em>(For each, expand information to include):</em></p>
<ul>
<li>Write up SIMs (Specific Internet Market Segment, <a href="http://www.amazon.com/Micro-ISV-Vision-Reality-Bob-Walsh/dp/1590596013/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1226760927&amp;sr=1-1">Walsh</a> pg 158..)
<ul>
<li>Lots of details about the targeted user group</li>
</ul>
</li>
<li>Other user information
<ul>
<li>How often do you expect each user group to user the product?</li>
<li>Why might they stop using the product?</li>
<li>Rough guess as to size of this market, e.g. # potential users?</li>
</ul>
</li>
<li>Are there other non-primary users?<br />
<em>(E.g. users who didn&#8217;t purchase, or just different group of users)</em></p>
<ul>
<li>Also describe their &#8220;problem&#8221; and how product solves it</li>
<li>Are they also potential buyers, or just users?</li>
<li>What subset of the feature list might they use?</li>
<li>What else differentiates them from primary user group?</li>
<li>Also write up SIM for this user group</li>
</ul>
</li>
<li>Bluesky one or more revenue models.  Answer for each:
<ul>
<li>What would this customer pay for this product?
<ul>
<li>Specify target price or range that might be tolerable</li>
</ul>
</li>
<li>One-time purchase or ongoing subscription?  (or a combination)</li>
<li>Pricing tiers?  If so, describe</li>
<li>Trial period?  If so, describe</li>
<li>If &gt;1 user group, repeat for other groups</li>
<li>What level of certainty do you have that they will purchase?</li>
<li>Why might they not purchase?  List reasons.</li>
<li>Possible ways to mitigate non-purchase reasons.</li>
<li>Does revenue model depend on continued use of the product?</li>
<li>How will you collect money?</li>
<li>What is your distribution channel?  (i.e. how do they receive product)</li>
<li>If ongoing subscription, describe what happens when they stop paying<br />
<em>(E.g. limited access)?</em></li>
</ul>
</li>
<li>Revenue model/estimates  (per yr)
<ul>
<li>Make rough estimate of ongoing costs, per user or account</li>
<li>List expected revenue per user, single or ongoing, per yr</li>
<li>Starting with desired annual revenue, describe # customers required to meet goal</li>
</ul>
</li>
<li>Marketing / Sales vision
<ul>
<li>How might product be branded?</li>
<li>How is product positioned (e.g. tagline)</li>
<li>How might you reach desired users?  (make aware)</li>
<li>What is selling proposition (argument to buy)?</li>
</ul>
</li>
<li>Competitive analysis
<ul>
<li>Assess and summarize competitive products that do similar/same thing as yours</li>
<li>What are their strengths/weaknesses?</li>
<li>Where can you improve on them?  To what degree?</li>
<li>What are you missing that competitors might have?</li>
</ul>
</li>
</ul>
</li>
</ul>
<p><span style="text-decoration:underline;">Initial Requirements Gathering<br />
</span><em>(Chap 2 of <a href="http://www.amazon.com/First-Software-Development-Brain-Friendly-Guides/dp/0596527357/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1226760981&amp;sr=1-1">Head First Software Development</a>)</em></p>
<ul>
<li>Generate quick list of basic ideas, 1-3 sentences each, Title/Description</li>
<li>Ask user questions to flesh out the list</li>
<li>Bluesky to generate feature lists (Title/Description)
<ul>
<li>Use other people</li>
<li>Okay to spit out non-functional stuff, like specific GUI thoughts, or architecture</li>
</ul>
</li>
<li>Build User Stories
<ul>
<li>Describe one thing</li>
<li>Language of the customer</li>
<li>Title/Description</li>
<li>1-3 sentences</li>
</ul>
</li>
<li>Pull out non-customer stories, save for later (design)</li>
<li>Refine initial set of user stories, w/customer feedback</li>
<li>Provide estimates for each user story
<ul>
<li>Include assumptions</li>
</ul>
</li>
<li>Team estimation and revision</li>
<li>Clarify assumptions w/users, if necessary</li>
<li>Break apart users stories that are &gt;15 days</li>
<li>Add up estimates to get estimate for total project</li>
</ul>
<p><span style="text-decoration:underline;">GUI Conceptualizing</span></p>
<ul>
<li>Select key use cases that need GUI concept</li>
<li>User interaction goals
<ul>
<li>Outline some key goals of user interaction model<br />
(E.g. discoverability, efficiency, slick animation, etc)</li>
<li>Describe user action requirements verbally for specific use cases</li>
</ul>
</li>
<li>Assess similar products&#8217; GUIs for similar use cases
<ul>
<li>Pros/cons of each</li>
</ul>
</li>
<li>For each use case selected
<ul>
<li>Paper prototype one or more possible GUIs</li>
<li>Storyboard any dynamic behavior</li>
<li>Brainstorm alternative approaches and paper prototype</li>
</ul>
</li>
<li>Identify common sequences of use cases  (e.g. find/edit)
<ul>
<li>Storyboard use case sequences</li>
<li>Brainstorm ways to optimize the storyboard/sequence</li>
</ul>
</li>
<li>Assess GUI model against several measures of good GUI design</li>
<li>Technical review of GUI feasibility
<ul>
<li>Build it, buy it, or freebie (part of tool or freeware)?</li>
<li>If build, rough guess as to effort</li>
<li>If buy, what is the cost?  One-time &amp; ongoing.</li>
</ul>
</li>
<li>Assess technical risk
<ul>
<li>Are there any aspects of GUI that need to be proven out?</li>
</ul>
</li>
<li>Hammer looking for nails
<ul>
<li>Make short list of most compelling GUI models in new products</li>
<li>Is there anywhere in product that you might use these models?</li>
</ul>
</li>
<li>Brainstorm user assistance model (help, wizards, demos, etc.&#8211;learning)</li>
<li>GUI models from competitors
<ul>
<li>If there are competitive products that compete in same space, summarize their main GUI elements.</li>
<li>Assess&#8212;is their GUI or user interaction model an asset or a liability?</li>
</ul>
</li>
<li>Review
<ul>
<li>Early review internally (not w/customers)</li>
<li>Review static screen mockups (e.g. paper prototypes)</li>
<li>Look at discoverability&#8211;obvious what it&#8217;s used for?</li>
<li>Aesthetics</li>
</ul>
</li>
</ul>
<p><span style="text-decoration:underline;">Identify Candidate Architecture</span></p>
<ul>
<li>Identify one possible architecture that could support the product</li>
<li>Identify any areas of technical risk</li>
<li>Discuss pros/cons/risks</li>
<li><em>[For more details, see <a href="http://www.amazon.com/Rational-Unified-Process-Made-Easy/dp/0321166094/ref=sr_1_2?ie=UTF8&amp;s=books&amp;qid=1226761135&amp;sr=1-2">Kroll</a>]</em></li>
</ul>
<p><span style="text-decoration:underline;">Define Non-Functional Tasks</span></p>
<ul>
<li>Define additional tasks to be completed during inception that are NOT use cases</li>
<li>Possible examples include:
<ul>
<li>GUI proof-of-concept, for technical &amp; usability</li>
<li>Building candidate architecture  (must do)</li>
<li>Technical proof-of-concept</li>
<li>Capacity testing for architecture (e.g. scalability)</li>
</ul>
</li>
<li>Provide priorities and estimates for all tasks<br />
(will feed into iteration planning, along w/use cases)</li>
</ul>
<p><span style="text-decoration:underline;">Define Iterations<br />
</span><em>(Chap 3 of <a href="http://www.amazon.com/First-Software-Development-Brain-Friendly-Guides/dp/0596527357/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1226760981&amp;sr=1-1">Head First Software Development</a>)</em></p>
<ul>
<li>Set target date for first (next) release</li>
<li>Work w/customer to prioritize user stories</li>
<li>Also feed non-functional tasks into process</li>
<li>Select subset of user stories to meet target date  (Milestone 1)
<ul>
<li>If the features don&#8217;t fit target date, re-prioritize</li>
<li>Focus on user stories that are absolutely critical</li>
<li>Baseline functionality&#8211;smallest set of features so that SW is at all useful to customers</li>
</ul>
</li>
<li>Prioritize user stories in Milestone 1.0  (1-5, with 1 as highest priority)</li>
<li>Assign user stories to iterations, using 20-day iterations
<ul>
<li>Based on priority</li>
<li>Or user stories required to implement other user stories</li>
</ul>
<ul>
<li>Use velocity of 0.7  (0.7days effort for each real day)<br />
<em>I.e. Each iteration should contain 14 person-days of estimated work</em></li>
</ul>
</li>
<li>Reassess schedule and adjust schedule and/or content
<ul>
<li>Because of velocity, things likely can&#8217;t fit</li>
<li>Add iteration(s), change M1 date, or both</li>
</ul>
</li>
<li>Get iterations &amp; user stories into tracking spreadsheet</li>
<li>Construct burn-down graph for 1st iteration
<ul>
<li>X axis is calendar days</li>
<li>Y axis is person-days of work accomplished</li>
<li>Draw diagonal line as ideal burn-down rate</li>
</ul>
</li>
</ul>
<p><span style="text-decoration:underline;">Write Development Plan</span></p>
<ul>
<li>Describe everything that will happen from here on out</li>
<li>Include
<ul>
<li>Iterations and contained user stories &amp; tasks</li>
<li>Milestones</li>
<li>Review points and staff</li>
<li>High-level test plan</li>
<li>alpha/beta/release plan</li>
<li>Staff</li>
<li>Schedule</li>
<li>Tools</li>
<li>Show steps in Product Development process</li>
<li>Show steps in Customer Development process</li>
<li>Show how the two processes line up</li>
<li>Include calendar alignment, if appropriate</li>
</ul>
</li>
</ul>
<p><span style="text-decoration:underline;">Execute Inception Iterations<br />
</span><em>(Chap 4 of <a href="http://www.amazon.com/First-Software-Development-Brain-Friendly-Guides/dp/0596527357/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1226760981&amp;sr=1-1">Head First Software Development</a> - User stories &amp; tasks)</em></p>
<ul>
<li>Break down each user story into tasks
<ul>
<li>Title/Description/Estimate</li>
<li>Provide estimate for each task</li>
<li>E.g. Create class, create GUI prototype, create schema, create SQL scripts</li>
<li>Each task should be 0.5 - 5 days</li>
</ul>
</li>
<li>Plot where you are on burn-down graph
<ul>
<li>Calendar day vs. new estimate of person-days of work left</li>
</ul>
</li>
<li>Update spreadsheet w/tasks &amp; their estimates
<ul>
<li>Task estimates replace user story estimates</li>
<li>Also track burn-down in spreadsheet</li>
<li>Put stickies on big board, tasks, In Progress/Complete, etc. (pg 116 of <a href="http://www.amazon.com/First-Software-Development-Brain-Friendly-Guides/dp/0596527357/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1226761187&amp;sr=1-1"><em>Pilone/Miles</em></a>)</li>
</ul>
</li>
<li>Start working on first tasks
<ul>
<li>Move stickies on board when they are <em>In Progress</em></li>
</ul>
</li>
<li>Daily stand-up meetings to track progress
<ul>
<li>First thing in the morning</li>
<li>Track progress&#8211;what has each person accomplished</li>
<li>Update burn-down rate</li>
<li>Update tasks</li>
<li>What happened yesterday, what is plan for today</li>
<li>Talk about any problems</li>
<li>5-15 mins long</li>
</ul>
</li>
<li>Add unplanned tasks to iteration, if necessary
<ul>
<li>Add user story, estimate, break into tasks, review w/customer, add to board</li>
<li>Use red stickies</li>
<li>Update burn-down, showing that you&#8217;re off</li>
</ul>
</li>
<li>Next iteration<br />
<em>(Chap 10 of <a href="http://www.amazon.com/First-Software-Development-Brain-Friendly-Guides/dp/0596527357/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1226760981&amp;sr=1-1">Head First Software Development</a>)</em></p>
<ul>
<li>End of iteration review (pg 342-343 of <a href="http://www.amazon.com/First-Software-Development-Brain-Friendly-Guides/dp/0596527357/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1226761187&amp;sr=1-1">Pilone/Miles</a>)</li>
<li>Verify SW passes all tests</li>
<li>Demo/review w/customer</li>
<li>Plan next iteration
<ul>
<li>Add new user stories, if required</li>
<li>Update priority/estimates for everything</li>
<li>Adjust velocity</li>
<li>Feed in bug backlog as tasks</li>
<li>Priority tradeoffs include bug-fixes vs. new features</li>
</ul>
</li>
<li>Follow steps from Pilone/Miles chap 4 (break down into tasks and estimate)</li>
</ul>
</li>
</ul>
<p><span style="text-decoration:underline;">Write Business Plan</span></p>
<ul>
<li>Goal isn&#8217;t to get funding, but to make a case for the product/business<br />
(at least on paper)</li>
<li>Include stuff like
<ul>
<li>Market description</li>
<li>Customer description</li>
<li>Description of competitors&#8217; products/services</li>
<li>Product proposition
<ul>
<li>What is customers&#8217; problem?</li>
<li>What is your vision for product/service</li>
<li>How does product/service solve their problem?</li>
</ul>
</li>
<li>Outline of development plan</li>
<li>Outline of Product/Customer Development processes</li>
<li>Summarize revenue model</li>
<li>Summarize marketing/sales plan</li>
<li>Business structure: staffing, organization, etc.</li>
</ul>
</li>
<li>Add other typical business plan elements</li>
</ul>
<p><span style="text-decoration:underline;">Write Test Plan</span></p>
<ul>
<li>What to test, how to test, when to test</li>
<li>Plan for test-driven development, using appropriate TDD tools</li>
<li>Plan automated/nightly builds and automation of testing</li>
<li>See <a href="http://www.amazon.com/First-Software-Development-Brain-Friendly-Guides/dp/0596527357/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1226761187&amp;sr=1-1"><em>Pilone/Miles</em></a>, chap 7, among others</li>
</ul>
<p><span style="text-decoration:underline;">Write Deployment Plan</span></p>
<ul>
<li>How/when will software be deployed?</li>
<li>Map out alpha/beta/launch</li>
<li>Where does testing fit into the plan?</li>
<li>How will customers get the software?</li>
<li>How will they pay for it?</li>
<li>How do you track customers?</li>
</ul>
<p><span style="text-decoration:underline;">Execute Construction Iterations<br />
</span><em>(Chap 4 of <a href="http://www.amazon.com/First-Software-Development-Brain-Friendly-Guides/dp/0596527357/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1226760981&amp;sr=1-1">Head First Software Development</a> - User stories &amp; tasks)</em></p>
<ul>
<li>Break down each user story into tasks
<ul>
<li>Title/Description/Estimate</li>
<li>Provide estimate for each task</li>
<li>E.g. Create class, create GUI prototype, create schema, create SQL scripts</li>
<li>Each task should be 0.5 - 5 days</li>
</ul>
</li>
<li>Plot where you are on burn-down graph
<ul>
<li>Calendar day vs. new estimate of person-days of work left</li>
</ul>
</li>
<li>Update spreadsheet w/tasks &amp; their estimates
<ul>
<li>Task estimates replace user story estimates</li>
<li>Also track burn-down in spreadsheet</li>
<li>Put stickies on big board, tasks, In Progress/Complete, etc. (pg 116 of <a href="http://www.amazon.com/First-Software-Development-Brain-Friendly-Guides/dp/0596527357/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1226761187&amp;sr=1-1"><em>Pilone/Miles</em></a>)</li>
</ul>
</li>
<li>Start working on first tasks
<ul>
<li>Move stickies on board when they are In Progress</li>
</ul>
</li>
<li>Daily stand-up meetings to track progress
<ul>
<li>First thing in the morning</li>
<li>Track progress&#8211;what has each person accomplished</li>
<li>Update burn-down rate</li>
<li>Update tasks</li>
<li>What happened yesterday, what is plan for today</li>
<li>Talk about any problems</li>
<li>5-15 mins long</li>
</ul>
</li>
<li>Add unplanned tasks to iteration, if necessary
<ul>
<li>Add user story, estimate, break into tasks, review w/customer, add to board</li>
<li>Use red stickies</li>
<li>Update burn-down, showing that you&#8217;re off</li>
</ul>
</li>
<li>Next iteration<br />
<em> (Chap 10 of <a href="http://www.amazon.com/First-Software-Development-Brain-Friendly-Guides/dp/0596527357/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1226760981&amp;sr=1-1">Head First Software Development</a>)</em></p>
<ul>
<li>End of iteration review (pg 342-343 of <a href="http://www.amazon.com/First-Software-Development-Brain-Friendly-Guides/dp/0596527357/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1226761187&amp;sr=1-1"><em>Pilone/Miles</em></a>)</li>
<li>Verify SW passes all tests</li>
<li>Demo/review w/customer</li>
<li>Plan next iteration
<ul>
<li>Add new user stories, if required</li>
<li>Update priority/estimates for everything</li>
<li>Adjust velocity</li>
<li>Feed in bug backlog as tasks</li>
<li>Priority tradeoffs include bug-fixes vs. new features</li>
</ul>
</li>
<li>Follow steps from <a href="http://www.amazon.com/First-Software-Development-Brain-Friendly-Guides/dp/0596527357/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1226761187&amp;sr=1-1"><em>Pilone/Miles</em></a>, chap 4 (break down into tasks and estimate)</li>
</ul>
</li>
</ul>
<p><span style="text-decoration:underline;">Initiate Test Plan</span></p>
<ul>
<li>Begin regular testing</li>
<li>Functional, integration, system test (no customer testing yet)</li>
</ul>
<p><span style="text-decoration:underline;">Deploy Alpha Release</span></p>
<ul>
<li>Outline goals for beta and exit criteria</li>
<li>Identify potential customers/users</li>
<li>Communicate w/users about goals &amp; feedback mechanism</li>
<li>Feeds into appropriate spot in Customer Development process
<ul>
<li>Possibly at end of each construction iteration</li>
</ul>
</li>
<li>Gather feedback and feed into development
<ul>
<li>E.g. Changes desired/required?</li>
</ul>
</li>
</ul>
<p><span style="text-decoration:underline;">Write Customer Support Plan</span></p>
<ul>
<li>How will customers be supported after software is deployed?</li>
<li>List main goal(s)</li>
<li>Decide on tools, e.g.
<ul>
<li>External issue tracking</li>
<li>FAQ sheets for tech support staff</li>
</ul>
</li>
<li>Decide on process(es), e.g.
<ul>
<li>Communication w/customer</li>
<li>Looking for answer in FAQ</li>
<li>How to communicate answer, if known</li>
<li>Get closure</li>
<li>2nd tier&#8211;investigate, look for workaround</li>
<li>Interaction between staff (e.g. support/development)</li>
<li>3rd tier&#8211;reported bug, e.g. give bug # and have traceback mechanism</li>
</ul>
</li>
<li>Escalation process</li>
</ul>
<p><span style="text-decoration:underline;">Execute Deployment Iteration</span></p>
<ul>
<li>Working on deployment tasks, e.g.
<ul>
<li>Installs/uninstalls</li>
<li>Distribution/delivery</li>
<li>Payment</li>
<li>Customer tracking</li>
</ul>
</li>
</ul>
<p><span style="text-decoration:underline;">Deploy Beta Release</span></p>
<ul>
<li>Outline goals for beta and exit criteria</li>
<li>Identify potential customers/users</li>
<li>Communicate w/users about goals &amp; feedback mechanism</li>
<li>Feeds into appropriate spot in Customer Development process
<ul>
<li>Likely after Deployment Iteration</li>
</ul>
</li>
<li>Gather feedback and feed into development
<ul>
<li>E.g. Changes desired/required?</li>
</ul>
</li>
<li>Beta should not last indefinitely</li>
</ul>
<p><span style="text-decoration:underline;">Launch Product</span></p>
<ul>
<li>Announce product</li>
<li>Launch it</li>
<li>Throw a big party</li>
</ul>
<p><span style="text-decoration:underline;">Begin Planning Next Release</span></p>
<ul>
<li>Post-mortem for Product/Customer Development processes</li>
<li>Lessons learned</li>
<li>Changes to process</li>
<li>Assess organize outstanding bugs
<ul>
<li>Prioritize, estimate</li>
</ul>
</li>
<li>Organize list of possible future features
<ul>
<li>Plan mechanism for using existing customers to get feedback on priorities</li>
<li>Prioritize, estimate</li>
</ul>
</li>
<li>Decide on schedule for next release</li>
<li>Map out iterations
<ul>
<li>Each iteration either bug-fixing or new development</li>
<li>Bug-fixing phase likely first</li>
</ul>
</li>
<li>Goal: All bugs fixed prior to next release</li>
<li>Continued refinement of plan, based on ongoing customer feedback</li>
<li>Back to start of Product/Customer Development processes for next release<br />
<em>(follow same processes, including updating relevant plans)</em></li>
</ul>
<p><strong>Customer Development Process&#8212;Details</strong></p>
<p>Here’s the detailed breakdown of the steps involved in the <strong>Customer Development Process</strong>.  This comes directly from <a href="http://www.amazon.com/Four-Steps-Epiphany-Steven-Blank/dp/0976470705/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1226761339&amp;sr=1-1"><em>Four Steps to the Epiphany</em></a>.</p>
<p><span style="text-decoration:underline;">Customer Discovery</span></p>
<ul>
<li>State hypotheses
<ul>
<li>Write briefs, state assumptions about product, customers, pricing, demand, competitors</li>
</ul>
</li>
<li>Test problem hypotheses
<ul>
<li>Test in front of potential customers</li>
</ul>
</li>
<li>Test product concept
<ul>
<li>Test product features in front of customers</li>
<li>Solves their problem?</li>
<li>Also test business model
<ul>
<li>Must-have?</li>
<li>Pricing</li>
<li>Distribution</li>
</ul>
</li>
</ul>
</li>
<li>Verify
<ul>
<li>You understand the customer&#8217;s problems</li>
<li>Your product solves these problems</li>
<li>Customers will pay for the product</li>
<li>You have in mind a profitable business model</li>
</ul>
</li>
<li>Repeat if necessary</li>
</ul>
<p><span style="text-decoration:underline;">Customer Validation</span></p>
<ul>
<li>Get Ready to Sell
<ul>
<li>Articulate value proposition</li>
<li>Prep sales materials &amp; collateral plan</li>
<li>Develop distribution channel plan</li>
<li>Develop sales roadmap</li>
<li>Hire sales closer</li>
<li>Synch up Product/Customer Dev teams on features/dates</li>
<li>Formalize advisory board</li>
</ul>
</li>
<li>Sell to Visionary Customers
<ul>
<li>Sell unfinished product</li>
<li>Answer all sales roadmap questions</li>
</ul>
</li>
<li>Develop Positioning
<ul>
<li>Initial positioning</li>
<li>Articulate belief about product and its place in the market</li>
</ul>
</li>
<li>Verify
<ul>
<li>Enough orders to prove we can sell?</li>
<li>Profitable sales model?</li>
<li>Profitable business model?</li>
<li>Can you scale the business?</li>
</ul>
</li>
<li>Repeat, if necessary</li>
</ul>
<p><span style="text-decoration:underline;">Customer Creation</span></p>
<ul>
<li>Get Ready to Launch
<ul>
<li>Market Type Questionnaire</li>
<li>Choose Market Type</li>
<li>Choose 1st Year Objectives</li>
</ul>
</li>
<li>Position company &amp; product
<ul>
<li>Select PR agency</li>
<li>Positioning audits</li>
<li>Positioning to market type</li>
</ul>
</li>
<li>Launch company &amp; product
<ul>
<li>Select launch type</li>
<li>Select customer audience</li>
<li>Select the messengers</li>
<li>Craft the messages</li>
<li>Message context</li>
</ul>
</li>
<li>Create demand
<ul>
<li>Demand creation strategy</li>
<li>Demand creation measurements</li>
<li>Iterate or exit</li>
</ul>
</li>
</ul>
<p><span style="text-decoration:underline;">Company Building</span></p>
<ul>
<li>Reach mainstream customers
<ul>
<li>Change “earlyvangelists” into mainstream customers</li>
<li>Manage sales growth by market type</li>
</ul>
</li>
<li>Review management / Create mission culture
<ul>
<li>Review management</li>
<li>Develop “mission-centric” culture</li>
</ul>
</li>
<li>Transition to functional departments
<ul>
<li>Set department mission statement</li>
<li>Set department roles by market type</li>
</ul>
</li>
<li>Build fast-response departments
<ul>
<li>Implement mission-centric management</li>
<li>Create an “information culture”</li>
<li>Build a “leadership culture”</li>
</ul>
</li>
</ul>
<p><strong>Closing Thoughts</strong></p>
<p>The key takeaway for me from Blank’s book was as follows:</p>
<p style="padding-left:30px;">It’s not enough to build a great product.  You must also build a product that the customers need and that they will buy.  It&#8217;s also criticial to find a workable business model to sell to the right customers at the right price.</p>
<p>If you haven’t yet read <a href="http://www.amazon.com/Four-Steps-Epiphany-Steven-Blank/dp/0976470705/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1226761339&amp;sr=1-1"><em>Four Steps to the Epiphany</em></a>, I’d really encourage you to go out and read it.  Then you can start thinking about how to develop your customers, as well as your product.</p>
<p><strong>Sources</strong></p>
<p>I’ve used the following sources, in varying degrees, for this post:</p>
<ul>
<li><a href="http://www.amazon.com/Four-Steps-Epiphany-Steven-Blank/dp/0976470705/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1226761339&amp;sr=1-1"><em>Four Steps to the Epiphany</em></a>, Blank, cafepress.com, 2006.</li>
<li><a href="http://www.amazon.com/Business-Software-Manager-Programmer-Entrepreneur/dp/074321580X/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1226761401&amp;sr=1-1"><em>The Business of Software</em></a>, Cusumano, Free Press, 2004.</li>
<li><a href="http://www.amazon.com/Rational-Unified-Process-Made-Easy/dp/0321166094/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1226761427&amp;sr=1-1"><em>The Rational Process Made Easy: A Practitioner’s Guide to the RUP</em></a>, Kroll, Addison-Wesley, 2003.</li>
<li><a href="http://www.amazon.com/Rapid-Development-Taming-Software-Schedules/dp/1556159005/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1226761451&amp;sr=1-1"><em>Rapid Development</em></a>, McConnell, Microsoft Press, 1996.</li>
<li><a href="http://www.amazon.com/First-Software-Development-Brain-Friendly-Guides/dp/0596527357/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1226761478&amp;sr=1-1"><em>Head First Software Development</em></a>, Pilone &amp; Miles, O’Reilly, 2008.</li>
<li><a href="http://www.amazon.com/Eric-Business-Software-Experts-Voice/dp/1590596234/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1226761497&amp;sr=1-1"><em>Eric Sink on the Business of Software</em></a>, Sink, Apress, 2006.</li>
<li><a href="http://www.amazon.com/Micro-ISV-Vision-Reality-Bob-Walsh/dp/1590596013/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1226761517&amp;sr=1-1"><em>Micro-ISV – From Vision to Reality</em></a>, Walsh, Apress, 2006.</li>
</ul>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/spsexton.wordpress.com/441/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/spsexton.wordpress.com/441/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/spsexton.wordpress.com/441/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/spsexton.wordpress.com/441/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/spsexton.wordpress.com/441/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/spsexton.wordpress.com/441/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/spsexton.wordpress.com/441/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/spsexton.wordpress.com/441/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/spsexton.wordpress.com/441/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/spsexton.wordpress.com/441/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=stuff.seans.com&blog=4003566&post=441&subd=spsexton&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://stuff.seans.com/2008/11/15/a-recipe-for-green-field-software-development/feed/</wfw:commentRss>
	
		<media:content url="http://www.gravatar.com/avatar/8922e4d5254d602ba3ed32dd073b5a4e?s=96&#38;d=identicon" medium="image">
			<media:title type="html">spsexton</media:title>
		</media:content>

		<media:content url="http://spsexton.files.wordpress.com/2008/11/rupmap.gif" medium="image">
			<media:title type="html">rupmap</media:title>
		</media:content>

		<media:content url="http://spsexton.files.wordpress.com/2008/11/rupphases.gif" medium="image">
			<media:title type="html">rupphases</media:title>
		</media:content>
	</item>
		<item>
		<title>Windows 7 Install Screenshots</title>
		<link>http://stuff.seans.com/2008/11/07/windows-7-install-screenshots/</link>
		<comments>http://stuff.seans.com/2008/11/07/windows-7-install-screenshots/#comments</comments>
		<pubDate>Fri, 07 Nov 2008 11:25:51 +0000</pubDate>
		<dc:creator>Sean</dc:creator>
		
		<category><![CDATA[Windows 7]]></category>

		<category><![CDATA[Blackcomb]]></category>

		<category><![CDATA[Installation]]></category>

		<category><![CDATA[Microsoft Windows]]></category>

		<category><![CDATA[Microsoft Windows 7]]></category>

		<category><![CDATA[Vienna]]></category>

		<category><![CDATA[Windows 7 Screenshots]]></category>

		<category><![CDATA[Windows Screenshots]]></category>

		<guid isPermaLink="false">http://spsexton.wordpress.com/?p=404</guid>
		<description><![CDATA[I thought I’d do my part to flood the web with screenshots from the M3 preview of Windows 7 that was distributed at last week’s Professional Development Conference in LA.
The obvious place to start in Win 7 is with the installation process.  I’ll put up more posts later with screenshots of various bits and pieces [...]]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>I thought I’d do my part to flood the web with screenshots from the M3 preview of Windows 7 that was distributed at last week’s Professional Development Conference in LA.</p>
<p>The obvious place to start in Win 7 is with the installation process.  I’ll put up more posts later with screenshots of various bits and pieces in Windows 7.  But this first post will just contain: <strong>every damn Windows 7 installation screen</strong>.</p>
<p>Ok, admittedly, looking through install screens is about as exciting as watching bacon fat congeal.  But really&#8212;there are people out there who will eat this stuff up.  So it’s for them that I’ve suffered an endless series of screen captures.  Enjoy.</p>
<p><strong>The Environment</strong></p>
<p>I installed my copy of Windows 7 to a VMWare virtual machine.  The only “gotcha” was that VMWare creates a SCSCI virtual hard drive by default&#8212;which Windows 7 failed to recognize.  Simple fix&#8212;just delete the default hard drive and create an IDE drive in VMWare.</p>
<p><strong>The Screens</strong></p>
<p>Ok, here we go.</p>
<p>You just get shivers as you start to install a new Microsoft OS for the first time, don’t you?</p>
<p><a href="http://spsexton.files.wordpress.com/2008/11/install-05.jpg"><img class="alignnone size-full wp-image-405" title="install-05" src="http://spsexton.files.wordpress.com/2008/11/install-05.jpg?w=1014&#038;h=759" alt="install-05" width="1014" height="759" /></a></p>
<p>Then we switch from a DOS-looking progress bar to a cute Windows-looking progress bar:</p>
<p><a href="http://spsexton.files.wordpress.com/2008/11/install-1.jpg"><img class="alignnone size-full wp-image-407" title="install-1" src="http://spsexton.files.wordpress.com/2008/11/install-1.jpg?w=647&#038;h=477" alt="install-1" width="647" height="477" /></a></p>
<p>Next we get the first Windows 7 install screen.  This is the spot to insert the angelic music.</p>
<p><a href="http://spsexton.files.wordpress.com/2008/11/install-2.jpg"><img class="alignnone size-full wp-image-408" title="install-2" src="http://spsexton.files.wordpress.com/2008/11/install-2.jpg?w=796&#038;h=599" alt="install-2" width="796" height="599" /></a></p>
<p>After picking an install language, you get to the main install kick-off window:</p>
<p><a href="http://spsexton.files.wordpress.com/2008/11/install-3.jpg"><img class="alignnone size-full wp-image-409" title="install-3" src="http://spsexton.files.wordpress.com/2008/11/install-3.jpg?w=799&#038;h=600" alt="install-3" width="799" height="600" /></a></p>
<p>I once met a guy who actually read these EULAs.  Can you believe it?</p>
<p><a href="http://spsexton.files.wordpress.com/2008/11/install-4.jpg"><img class="alignnone size-full wp-image-410" title="install-4" src="http://spsexton.files.wordpress.com/2008/11/install-4.jpg?w=799&#038;h=596" alt="install-4" width="799" height="596" /></a></p>
<p>This next dialog is just as confusing in Windows 7 as it was in Vista.</p>
<p><a href="http://spsexton.files.wordpress.com/2008/11/install-5.jpg"><img class="alignnone size-full wp-image-411" title="install-5" src="http://spsexton.files.wordpress.com/2008/11/install-5.jpg?w=801&#038;h=598" alt="install-5" width="801" height="598" /></a></p>
<p>In my first try, I went with the Upgrade option, which only got me this next confusing empty dialog.  Nice.</p>
<p><a href="http://spsexton.files.wordpress.com/2008/11/install-6.jpg"><img class="alignnone size-full wp-image-412" title="install-6" src="http://spsexton.files.wordpress.com/2008/11/install-6.jpg?w=800&#038;h=600" alt="install-6" width="800" height="600" /></a></p>
<p>Restarting everything and instead choosing Custom gets us where we want to go:</p>
<p><a href="http://spsexton.files.wordpress.com/2008/11/install-7.jpg"><img class="alignnone size-full wp-image-413" title="install-7" src="http://spsexton.files.wordpress.com/2008/11/install-7.jpg?w=803&#038;h=596" alt="install-7" width="803" height="596" /></a></p>
<p>If you click on the link that reads “Drive options (advanced)”, you’ll see some options for managing hard disk partitions:</p>
<p><a href="http://spsexton.files.wordpress.com/2008/11/install-8.jpg"><img class="alignnone size-full wp-image-414" title="install-8" src="http://spsexton.files.wordpress.com/2008/11/install-8.jpg?w=808&#038;h=602" alt="install-8" width="808" height="602" /></a></p>
<p>Finally, the actual installation begins.</p>
<p><a href="http://spsexton.files.wordpress.com/2008/11/install-9.jpg"><img class="alignnone size-full wp-image-415" title="install-9" src="http://spsexton.files.wordpress.com/2008/11/install-9.jpg?w=803&#038;h=601" alt="install-9" width="803" height="601" /></a></p>
<p>At some point, near the end of the installation, Windows boots for the first time.  It lives!</p>
<p><a href="http://spsexton.files.wordpress.com/2008/11/install-10.jpg"><img class="alignnone size-full wp-image-416" title="install-10" src="http://spsexton.files.wordpress.com/2008/11/install-10.jpg?w=1021&#038;h=768" alt="install-10" width="1021" height="768" /></a></p>
<p>This was an interesting detail during the boot process:</p>
<p><a href="http://spsexton.files.wordpress.com/2008/11/install-11.jpg"><img class="alignnone size-full wp-image-417" title="install-11" src="http://spsexton.files.wordpress.com/2008/11/install-11.jpg?w=1021&#038;h=765" alt="install-11" width="1021" height="765" /></a></p>
<p>All of the services apparently start firing up, as the boot process continues.  (Hallelujah)!</p>
<p><a href="http://spsexton.files.wordpress.com/2008/11/install-12.jpg"><img class="alignnone size-full wp-image-418" title="install-12" src="http://spsexton.files.wordpress.com/2008/11/install-12.jpg?w=1020&#038;h=766" alt="install-12" width="1020" height="766" /></a></p>
<p>And for some reason, we’re allowed to go back and look at this status dialog one more time.</p>
<p><a href="http://spsexton.files.wordpress.com/2008/11/install-13.jpg"><img class="alignnone size-full wp-image-419" title="install-13" src="http://spsexton.files.wordpress.com/2008/11/install-13.jpg?w=1022&#038;h=767" alt="install-13" width="1022" height="767" /></a></p>
<p>And then back to the main boot screen.  (Are you starting to feel as if you were really there)?</p>
<p><a href="http://spsexton.files.wordpress.com/2008/11/install-14.jpg"><img class="alignnone size-full wp-image-420" title="install-14" src="http://spsexton.files.wordpress.com/2008/11/install-14.jpg?w=1024&#038;h=768" alt="install-14" width="1024" height="768" /></a></p>
<p>Oh, this is a nice little touch.  No screen flickers or anything, but nice to know that it’s “checking” my video performance.  (Whatever that means).</p>
<p><a href="http://spsexton.files.wordpress.com/2008/11/install-15.jpg"><img class="alignnone size-full wp-image-421" title="install-15" src="http://spsexton.files.wordpress.com/2008/11/install-15.jpg?w=1022&#038;h=765" alt="install-15" width="1022" height="765" /></a></p>
<p>Now Windows is more or less running and we start doing some of the final configuration stuff.  First, we specify a default username.  This will be the Administrator user account.  Seeing a PC name of &#8220;PC&#8221; also makes me think of John Hodgman and the Mac switcher ads.</p>
<p><a href="http://spsexton.files.wordpress.com/2008/11/install-16.jpg"><img class="alignnone size-full wp-image-422" title="install-16" src="http://spsexton.files.wordpress.com/2008/11/install-16.jpg?w=1023&#038;h=767" alt="install-16" width="1023" height="767" /></a></p>
<p>And I enter my password:</p>
<p><a href="http://spsexton.files.wordpress.com/2008/11/install-17.jpg"><img class="alignnone size-full wp-image-423" title="install-17" src="http://spsexton.files.wordpress.com/2008/11/install-17.jpg?w=1023&#038;h=766" alt="install-17" width="1023" height="766" /></a></p>
<p>And (of course) the product activation key.  Wouldn’t it be cool if every key had a barcode and I could use a barcode scanner at this point?  (My key did <strong>not</strong> have a barcode).</p>
<p><a href="http://spsexton.files.wordpress.com/2008/11/install-18.jpg"><img class="alignnone size-full wp-image-424" title="install-18" src="http://spsexton.files.wordpress.com/2008/11/install-18.jpg?w=1023&#038;h=767" alt="install-18" width="1023" height="767" /></a></p>
<p>I also get to set my time and time zone.</p>
<p><a href="http://spsexton.files.wordpress.com/2008/11/install-19.jpg"><img class="alignnone size-full wp-image-425" title="install-19" src="http://spsexton.files.wordpress.com/2008/11/install-19.jpg?w=1023&#038;h=766" alt="install-19" width="1023" height="766" /></a></p>
<p>This is an interesting one.  Right out of the gate, I’m asked to specify whether my network is public or not.  Like Vista, this dictates some default security settings.</p>
<p><a href="http://spsexton.files.wordpress.com/2008/11/install-20.jpg"><img class="alignnone size-full wp-image-426" title="install-20" src="http://spsexton.files.wordpress.com/2008/11/install-20.jpg?w=1024&#038;h=766" alt="install-20" width="1024" height="766" /></a></p>
<p>I picked Home network and Windows 7 did some remaining network configuration work.</p>
<p><a href="http://spsexton.files.wordpress.com/2008/11/install-21.jpg"><img class="alignnone size-full wp-image-427" title="install-21" src="http://spsexton.files.wordpress.com/2008/11/install-21.jpg?w=1020&#038;h=766" alt="install-21" width="1020" height="766" /></a></p>
<p>Ok, here’s one of the first really new things to show up.  A “homegroup” is basically a relabeled “workgroup”&#8212;something short of a domain.  I’m wondering if I’d chosen Work location in the earlier screen, if I’d now be joining a domain.</p>
<p><a href="http://spsexton.files.wordpress.com/2008/11/install-22.jpg"><img class="alignnone size-full wp-image-428" title="install-22" src="http://spsexton.files.wordpress.com/2008/11/install-22.jpg?w=1023&#038;h=765" alt="install-22" width="1023" height="765" /></a></p>
<p>Finally, we are “welcomed” to Windows 7.</p>
<p><a href="http://spsexton.files.wordpress.com/2008/11/install-23.jpg"><img class="alignnone size-full wp-image-429" title="install-23" src="http://spsexton.files.wordpress.com/2008/11/install-23.jpg?w=1023&#038;h=767" alt="install-23" width="1023" height="767" /></a></p>
<p>We’re so close, I can taste it.</p>
<p><a href="http://spsexton.files.wordpress.com/2008/11/install-24.jpg"><img class="alignnone size-full wp-image-430" title="install-24" src="http://spsexton.files.wordpress.com/2008/11/install-24.jpg?w=1024&#038;h=766" alt="install-24" width="1024" height="766" /></a></p>
<p>And voila!  The Windows 7 installation is complete and we’re sitting at the desktop screen.  Note that I don’t have that cool new taskbar in the build that was handed out at PDC.  More on that next time&#8212;the new taskbar is actually in the build and Rafael Rivera has found a hack to unlock it.</p>
<p><a href="http://spsexton.files.wordpress.com/2008/11/install-25.jpg"><img class="alignnone size-full wp-image-431" title="install-25" src="http://spsexton.files.wordpress.com/2008/11/install-25.jpg?w=1024&#038;h=765" alt="install-25" width="1024" height="765" /></a></p>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/spsexton.wordpress.com/404/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/spsexton.wordpress.com/404/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/spsexton.wordpress.com/404/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/spsexton.wordpress.com/404/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/spsexton.wordpress.com/404/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/spsexton.wordpress.com/404/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/spsexton.wordpress.com/404/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/spsexton.wordpress.com/404/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/spsexton.wordpress.com/404/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/spsexton.wordpress.com/404/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=stuff.seans.com&blog=4003566&post=404&subd=spsexton&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://stuff.seans.com/2008/11/07/windows-7-install-screenshots/feed/</wfw:commentRss>
	
		<media:content url="http://www.gravatar.com/avatar/8922e4d5254d602ba3ed32dd073b5a4e?s=96&#38;d=identicon" medium="image">
			<media:title type="html">spsexton</media:title>
		</media:content>

		<media:content url="http://spsexton.files.wordpress.com/2008/11/install-05.jpg" medium="image">
			<media:title type="html">install-05</media:title>
		</media:content>

		<media:content url="http://spsexton.files.wordpress.com/2008/11/install-1.jpg" medium="image">
			<media:title type="html">install-1</media:title>
		</media:content>

		<media:content url="http://spsexton.files.wordpress.com/2008/11/install-2.jpg" medium="image">
			<media:title type="html">install-2</media:title>
		</media:content>

		<media:content url="http://spsexton.files.wordpress.com/2008/11/install-3.jpg" medium="image">
			<media:title type="html">install-3</media:title>
		</media:content>

		<media:content url="http://spsexton.files.wordpress.com/2008/11/install-4.jpg" medium="image">
			<media:title type="html">install-4</media:title>
		</media:content>

		<media:content url="http://spsexton.files.wordpress.com/2008/11/install-5.jpg" medium="image">
			<media:title type="html">install-5</media:title>
		</media:content>

		<media:content url="http://spsexton.files.wordpress.com/2008/11/install-6.jpg" medium="image">
			<media:title type="html">install-6</media:title>
		</media:content>

		<media:content url="http://spsexton.files.wordpress.com/2008/11/install-7.jpg" medium="image">
			<media:title type="html">install-7</media:title>
		</media:content>

		<media:content url="http://spsexton.files.wordpress.com/2008/11/install-8.jpg" medium="image">
			<media:title type="html">install-8</media:title>
		</media:content>

		<media:content url="http://spsexton.files.wordpress.com/2008/11/install-9.jpg" medium="image">
			<media:title type="html">install-9</media:title>
		</media:content>

		<media:content url="http://spsexton.files.wordpress.com/2008/11/install-10.jpg" medium="image">
			<media:title type="html">install-10</media:title>
		</media:content>

		<media:content url="http://spsexton.files.wordpress.com/2008/11/install-11.jpg" medium="image">
			<media:title type="html">install-11</media:title>
		</media:content>

		<media:content url="http://spsexton.files.wordpress.com/2008/11/install-12.jpg" medium="image">
			<media:title type="html">install-12</media:title>
		</media:content>

		<media:content url="http://spsexton.files.wordpress.com/2008/11/install-13.jpg" medium="image">
			<media:title type="html">install-13</media:title>
		</media:content>

		<media:content url="http://spsexton.files.wordpress.com/2008/11/install-14.jpg" medium="image">
			<media:title type="html">install-14</media:title>
		</media:content>

		<media:content url="http://spsexton.files.wordpress.com/2008/11/install-15.jpg" medium="image">
			<media:title type="html">install-15</media:title>
		</media:content>

		<media:content url="http://spsexton.files.wordpress.com/2008/11/install-16.jpg" medium="image">
			<media:title type="html">install-16</media:title>
		</media:content>

		<media:content url="http://spsexton.files.wordpress.com/2008/11/install-17.jpg" medium="image">
			<media:title type="html">install-17</media:title>
		</media:content>

		<media:content url="http://spsexton.files.wordpress.com/2008/11/install-18.jpg" medium="image">
			<media:title type="html">install-18</media:title>
		</media:content>

		<media:content url="http://spsexton.files.wordpress.com/2008/11/install-19.jpg" medium="image">
			<media:title type="html">install-19</media:title>
		</media:content>

		<media:content url="http://spsexton.files.wordpress.com/2008/11/install-20.jpg" medium="image">
			<media:title type="html">install-20</media:title>
		</media:content>

		<media:content url="http://spsexton.files.wordpress.com/2008/11/install-21.jpg" medium="image">
			<media:title type="html">install-21</media:title>
		</media:content>

		<media:content url="http://spsexton.files.wordpress.com/2008/11/install-22.jpg" medium="image">
			<media:title type="html">install-22</media:title>
		</media:content>

		<media:content url="http://spsexton.files.wordpress.com/2008/11/install-23.jpg" medium="image">
			<media:title type="html">install-23</media:title>
		</media:content>

		<media:content url="http://spsexton.files.wordpress.com/2008/11/install-24.jpg" medium="image">
			<media:title type="html">install-24</media:title>
		</media:content>

		<media:content url="http://spsexton.files.wordpress.com/2008/11/install-25.jpg" medium="image">
			<media:title type="html">install-25</media:title>
		</media:content>
	</item>
		<item>
		<title>Session – WPF: Extensible BitmapEffects, Pixel Shaders, and WPF Graphics Futures</title>
		<link>http://stuff.seans.com/2008/11/06/session-%e2%80%93-wpf-extensible-bitmapeffects-pixel-shaders-and-wpf-graphics-futures/</link>
		<comments>http://stuff.seans.com/2008/11/06/session-%e2%80%93-wpf-extensible-bitmapeffects-pixel-shaders-and-wpf-graphics-futures/#comments</comments>
		<pubDate>Thu, 06 Nov 2008 18:11:32 +0000</pubDate>
		<dc:creator>Sean</dc:creator>
		
		<category><![CDATA[PDC 2008]]></category>

		<category><![CDATA[WPF]]></category>

		<category><![CDATA[Direct3D]]></category>

		<category><![CDATA[HLSL]]></category>

		<category><![CDATA[Microsoft PDC]]></category>

		<category><![CDATA[pdc08]]></category>

		<category><![CDATA[pdc2008]]></category>

		<category><![CDATA[Pixel Shaders]]></category>

		<guid isPermaLink="false">http://spsexton.wordpress.com/?p=398</guid>
		<description><![CDATA[PDC 2008, Day #4, Session #4, 1 hr 15 mins
David Teitlebaum
Program Manager
WPF Team
My final session at PDC 2008 was a talk about the improvements in WPF graphics that are available in .NET Framework 3.5 SP1.  David also touched briefly some possible future features (i.e. that would appear in .NET Framework 4.0).
David’s main topic was to [...]]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><em>PDC 2008, Day #4, Session #4, 1 hr 15 mins</em></p>
<p><em>David Teitlebaum<br />
Program Manager<br />
WPF Team</em></p>
<p>My final session at PDC 2008 was a talk about the improvements in WPF graphics that are available in .NET Framework 3.5 SP1.  David also touched briefly some possible future features (i.e. that would appear in .NET Framework 4.0).</p>
<p>David’s main topic was to walk through the details of the new Shader Effects model, which replaces the old Bitmap Effects feature.</p>
<p><strong>What are Bitmap Effects?</strong></p>
<p>These are effects that are applied to an individual UI element, like a button, to create some desired visual effect.  This includes things like drop shadow, bevels and blur effects.</p>
<p><strong>BitmapEffect</strong></p>
<p>The BitmapEffect object was introduced in Framework 3.0 (the first WPF release).  But there were some problems with it, that led to now replacing it with Shader Effects in 3.5SP1.</p>
<p>Problems with BitmapEffect:</p>
<ul>
<li>They were rendered in software</li>
<li>Blur operations were very slow</li>
<li>There were various limitations, including no ClearType support, no anisotripic filtering, etc.</li>
</ul>
<p><strong>New Shader Effects</strong></p>
<p>Basic characteristics in the new Shader Effects include:</p>
<ul>
<li>GPU accelerated</li>
<li>Have implemented hardware acceleration of the most popular bitmap effects
<ul>
<li>But did <strong>not </strong>implement outer glow</li>
</ul>
</li>
<li>Can author custom hardware-accelerated bitmap effects using HLSL</li>
<li>There is a software-only fallback pipeline that is actually faster than the old Bitmap Effects</li>
<li>New Shader Effects run on most video cards
<ul>
<li>Require PixelShader 2.0, which is about 5 years old</li>
</ul>
</li>
</ul>
<p><strong>How Do You Do Shader Effects?</strong></p>
<p>Here’s an outline of how you use the new Shader Effect model:</p>
<ul>
<li>Derive a custom class from the new <strong>ShaderEffect </strong>class (which derives from <strong>Effect</strong>)</li>
<li>You write your actual pixel shader code in HLSL, which is used for doing custom hardware-accelerated stuff using Direct3D
<ul>
<li>Language is C-like</li>
<li>Compiled to byte-code, consumed by video driver, runs on GPU</li>
</ul>
</li>
<li>Some more details about HLSL, as used in WPF
<ul>
<li>DirectX 10 supports HLSL 4.0</li>
<li>WPF currently only supports Pixelshader 2.0</li>
</ul>
</li>
</ul>
<p>So what do pixel shaders really do?  They basically take in a texture (bitmap) as input, do some processing on each point, and return a revised texture as an output.</p>
<p>Basically, you have a <strong>main </strong>function that accepts the coordinates of the current single pixel to be mapped.  Your code then accesses the original input texture through a register, so it just uses the input parameter (X/Y coordinate) to index into the source texture.  It then does some processing on the pixel in question and returns a color value.  This resultant color value just represents&#8212;the resulting RGB color at the specified coordinate.</p>
<p>The final step is to create, in managed code, a class that derives from <strong>ShaderEffect </strong>and hook it up to the pixel shader code (e.g. xyz.ps file) that you wrote.  You can then apply your shader to any WPF UIElement using XAML.  (By setting the <strong>Effect </strong>property).</p>
<p><strong>Direct3D Interop</strong></p>
<p>David’s next topic was to talk a bit about interop’ing with Direct3D.  This just means that your WPF application can easily host Direct3D content by using a new class called <strong>D3DImage.</strong></p>
<p>This was pretty cool.  David demoed displaying a Direct3D wireframe in the background (WPF 3D subsystem can’t do wireframes), with WPF GUI elements in the foreground, overlaying the background image.</p>
<p>The basic idea is that you create a Direct3D device in unmanaged code and then hook it to a new instance of a WPF D3DImage element, which you include in your visual hierarchy.</p>
<p><strong>WPF Futures</strong></p>
<p>Finally, David touched very briefly on some possible future features.  These are things that may show up in WPF 4.0 (.NET Framework 4.0), or possibly beyond that.</p>
<p>Some of the features likely included in WPF 4.0 include:</p>
<ul>
<li>Increased graphical richness  (e.g. Pixelshader 3.0)</li>
<li>Offloading more work to the GPU</li>
<li>Better rendering quality
<ul>
<li>Integrate DirectWrite for text clarity</li>
<li>Layout rounding</li>
</ul>
</li>
</ul>
<p>And some of the possible post-4.0 features include:</p>
<ul>
<li>Better exploitation of hardware</li>
<li>Vertex shaders</li>
<li>Shader groups</li>
<li>Shaders in WPF 3D</li>
<li>3D improvements</li>
<li>Better media extensibility</li>
</ul>
<p>References</p>
<p>You can get at David’s PDC08 slide deck for this talk here: <a href="http://mschnlnine.vo.llnwd.net/d1/pdc08/PPTX/PC07.pptx">http://mschnlnine.vo.llnwd.net/d1/pdc08/PPTX/PC07.pptx</a></p>
<p>And you can find full video from the session at:  <a href="http://mschnlnine.vo.llnwd.net/d1/pdc08/WMV-HQ/PC07.wmv">http://mschnlnine.vo.llnwd.net/d1/pdc08/WMV-HQ/PC07.wmv</a></p>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/spsexton.wordpress.com/398/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/spsexton.wordpress.com/398/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/spsexton.wordpress.com/398/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/spsexton.wordpress.com/398/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/spsexton.wordpress.com/398/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/spsexton.wordpress.com/398/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/spsexton.wordpress.com/398/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/spsexton.wordpress.com/398/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/spsexton.wordpress.com/398/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/spsexton.wordpress.com/398/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=stuff.seans.com&blog=4003566&post=398&subd=spsexton&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://stuff.seans.com/2008/11/06/session-%e2%80%93-wpf-extensible-bitmapeffects-pixel-shaders-and-wpf-graphics-futures/feed/</wfw:commentRss>
<enclosure url="http://mschnlnine.vo.llnwd.net/d1/pdc08/WMV-HQ/PC07.wmv" length="330737519" type="video/x-ms-wmv" />
	
		<media:content url="http://www.gravatar.com/avatar/8922e4d5254d602ba3ed32dd073b5a4e?s=96&#38;d=identicon" medium="image">
			<media:title type="html">spsexton</media:title>
		</media:content>
	</item>
		<item>
		<title>Session – Windows 7: Unlocking the GPU with Direct3D</title>
		<link>http://stuff.seans.com/2008/11/01/session-%e2%80%93-windows-7-unlocking-the-gpu-with-direct3d/</link>
		<comments>http://stuff.seans.com/2008/11/01/session-%e2%80%93-windows-7-unlocking-the-gpu-with-direct3d/#comments</comments>
		<pubDate>Sat, 01 Nov 2008 12:48:28 +0000</pubDate>
		<dc:creator>Sean</dc:creator>
		
		<category><![CDATA[PDC 2008]]></category>

		<category><![CDATA[Direct3D]]></category>

		<category><![CDATA[DirectX]]></category>

		<category><![CDATA[DirectX 10]]></category>

		<category><![CDATA[DirectX 11]]></category>

		<category><![CDATA[DirectX 9]]></category>

		<category><![CDATA[Microsoft PDC]]></category>

		<category><![CDATA[pdc08]]></category>

		<category><![CDATA[pdc2008]]></category>

		<category><![CDATA[Windows 7]]></category>

		<category><![CDATA[Windows Vista]]></category>

		<guid isPermaLink="false">http://spsexton.wordpress.com/?p=394</guid>
		<description><![CDATA[PDC 2008, Day #4, Session #3, 1 hr 15 mins
Allison Klein
I jumped off the Azure track (starting to be a bit repetitive) and next went to a session focused on Direct3D.
Despite the title, this session really had nothing to do with Windows 7, other than the fact that it talked a  lot about Direct3D 11, [...]]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><em>PDC 2008, Day #4, Session #3, 1 hr 15 mins</em></p>
<p><em>Allison Klein</em></p>
<p>I jumped off the Azure track (starting to be a bit repetitive) and next went to a session focused on Direct3D.</p>
<p>Despite the title, this session really had nothing to do with Windows 7, other than the fact that it talked a  lot about Direct3D 11, which will be included in Windows 7 and available for Windows Vista.</p>
<p><strong>Direct3D 10</strong></p>
<p>Direct3D 10 is the currently shipping version, and supported by most (all?) modern video cards, as well as integrated graphics chips.  I’m not entirely sure, but I think that Direct3D 10 shipped out-of-the-box with Windows Vista.  It is also available for Windows XP.</p>
<p>Allison spent about half of the talk going through things that are different in Direct3D 10, as compared with Direct3D 9.</p>
<p>I’m not inclined to rehash all of the details.  (I’ll include a link to Allison’s slide deck when it is available).</p>
<p>The main takeaway was that it’s very much worth programming to the v10 API, as opposed to the v9 API.  Some of the reasons for this include:</p>
<ul>
<li>Much more consistent behavior, across devices</li>
<li>Cleaner API</li>
<li>Elimination of large CAPS (device capability) matrix, for a more consistent experience across devices</li>
<li>Built-in driver that allows D3D10 to talk to D3D9 hardware</li>
<li>Addition of WARP 10 software rasterizer, to support devices that don’t support WDDM directly.  This is actually quite a bit faster than earlier software-only implementations</li>
</ul>
<p><strong>Direct3D 11</strong></p>
<p>In the second half of her talk, Allison talked about the advances coming in Direct3D 11.  She mentioned that D3D11 will ship with Windows 7 and also be available for Windows Vista.</p>
<p>Again, the details are probably more appropriate for a game developer.  (See the slide deck).  But the high level points are:</p>
<ul>
<li>Direct3D 11 is a strict superset of 10&#8212;there are no changes to existing 10 features</li>
<li>Better support for character authoring, for denser meshes and more detailed characters</li>
<li>Addition of tessellation to the rendering pipeline, for better performance and quality</li>
<li>Much more scalable multi-threading support.
<ul>
<li>Much more flexibility in what can be distributed across threads</li>
</ul>
</li>
<li>Dynamically linking in custom shaders</li>
<li>Introduction of object-oriented features (interfaces/classes) to HLSL</li>
<li>New block compression</li>
<li>Direct3D11 will be available in the Nov 2008 SDK</li>
</ul>
<p><strong>Futures</strong></p>
<p>Finally, Allison touched briefly on some future directions that the Direct3D is thinking about.</p>
<p>The main topic that she talked about here was in potentially using the GPU to perform highly parallel general purpose compute intensive tasks.  The developer would use HLSL to write a “compute shader”, which would then get sent to the GPU to do the work.  As an example, she talked about using this mechanism for post-processing of an image.</p>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/spsexton.wordpress.com/394/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/spsexton.wordpress.com/394/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/spsexton.wordpress.com/394/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/spsexton.wordpress.com/394/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/spsexton.wordpress.com/394/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/spsexton.wordpress.com/394/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/spsexton.wordpress.com/394/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/spsexton.wordpress.com/394/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/spsexton.wordpress.com/394/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/spsexton.wordpress.com/394/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=stuff.seans.com&blog=4003566&post=394&subd=spsexton&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://stuff.seans.com/2008/11/01/session-%e2%80%93-windows-7-unlocking-the-gpu-with-direct3d/feed/</wfw:commentRss>
	
		<media:content url="http://www.gravatar.com/avatar/8922e4d5254d602ba3ed32dd073b5a4e?s=96&#38;d=identicon" medium="image">
			<media:title type="html">spsexton</media:title>
		</media:content>
	</item>
		<item>
		<title>Session – Services Symposium: Enterprise Grade Cloud Applications</title>
		<link>http://stuff.seans.com/2008/11/01/session-%e2%80%93-services-symposium-enterprise-grade-cloud-applications/</link>
		<comments>http://stuff.seans.com/2008/11/01/session-%e2%80%93-services-symposium-enterprise-grade-cloud-applications/#comments</comments>
		<pubDate>Sat, 01 Nov 2008 12:41:15 +0000</pubDate>
		<dc:creator>Sean</dc:creator>
		
		<category><![CDATA[Azure]]></category>

		<category><![CDATA[PDC 2008]]></category>

		<category><![CDATA[cloud]]></category>

		<category><![CDATA[Cloud service]]></category>

		<category><![CDATA[Microsoft PDC]]></category>

		<category><![CDATA[pdc08]]></category>

		<category><![CDATA[pdc2008]]></category>

		<category><![CDATA[Software+Services]]></category>

		<category><![CDATA[Windows Azure]]></category>

		<guid isPermaLink="false">http://spsexton.wordpress.com/?p=387</guid>
		<description><![CDATA[PDC 2008, Day #4, Session #2, 1 hr 30 mins
Eugenio Pace
My second session on Thursday was a continuation of the cloud services symposium from the first session.  There was a third part to the symposium, which I did not attend.
The presenter for this session, Eugenio, was not nearly as good a presenter as Gianpaolo from [...]]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><em>PDC 2008, Day #4, Session #2, 1 hr 30 mins</em></p>
<p><em>Eugenio Pace</em></p>
<p>My second session on Thursday was a continuation of the cloud services symposium from the first session.  There was a third part to the symposium, which I did not attend.</p>
<p>The presenter for this session, Eugenio, was not nearly as good a presenter as Gianpaolo from the previous session.  So it was a bit less dynamic, and harder to stay interested.</p>
<p>The session basically consisted of a single demo, which illustrated some of the possible solutions to the Identity, Monitoring, and Integration challenges mentioned in the previous session.</p>
<p><strong>Identity</strong></p>
<p>Eugenio pointed out the problems involved in authentication/authorization.  You don’t want to require the enterprise users to have a unique username/password combination for each service that they use.  And pushing out the enterprise (e.g. Active Directory) credential information to the third party service is not secure and creates a management nightmare.</p>
<p>The proposed solution is to use a central (federated) identity system to do the authentication and authorization.  This is the purpose of the Azure Access Control service.</p>
<p><strong>Management</strong></p>
<p>The next part of the demo showed how Azure supports remote management, on the part of IT staff at an individual customer site, of their instance of your application.  The basic things that you can do remotely include:</p>
<ul>
<li>Active real-time monitoring of application health</li>
<li>Trigger administrative actions, based on the current state</li>
</ul>
<p>The end result (and goal) is that you have the same scope of control over your application as you’d have if it were on premises.</p>
<p><strong>Application Integration</strong></p>
<p>Finally, Eugenio did some demos related to “process integration”&#8212;allowing your service to be called from a legacy service or system.  This demo actually woke everyone up, because Eugenio brought an archaic green-screen AS400 system up in an emulator and proceeded to have it talk to his Azure service.</p>
<p><strong>Takeaways</strong></p>
<p>The conclusions were recommendations to both IT organizations and ISVs:</p>
<ul>
<li>Enterprise IT organization
<ul>
<li>Don’t settle for sub-optimal solutions</li>
<li>Tap into the benefits of Software+Services</li>
</ul>
</li>
<li>ISV
<ul>
<li>Don’t give them an excuse to reject your solution</li>
<li>Make use of better tools, frameworks, and services</li>
</ul>
</li>
</ul>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/spsexton.wordpress.com/387/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/spsexton.wordpress.com/387/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/spsexton.wordpress.com/387/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/spsexton.wordpress.com/387/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/spsexton.wordpress.com/387/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/spsexton.wordpress.com/387/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/spsexton.wordpress.com/387/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/spsexton.wordpress.com/387/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/spsexton.wordpress.com/387/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/spsexton.wordpress.com/387/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=stuff.seans.com&blog=4003566&post=387&subd=spsexton&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://stuff.seans.com/2008/11/01/session-%e2%80%93-services-symposium-enterprise-grade-cloud-applications/feed/</wfw:commentRss>
	
		<media:content url="http://www.gravatar.com/avatar/8922e4d5254d602ba3ed32dd073b5a4e?s=96&#38;d=identicon" medium="image">
			<media:title type="html">spsexton</media:title>
		</media:content>
	</item>
		<item>
		<title>Session – Services Symposium: Expanding Applications to the Cloud</title>
		<link>http://stuff.seans.com/2008/11/01/session-%e2%80%93-services-symposium-expanding-applications-to-the-cloud/</link>
		<comments>http://stuff.seans.com/2008/11/01/session-%e2%80%93-services-symposium-expanding-applications-to-the-cloud/#comments</comments>
		<pubDate>Sat, 01 Nov 2008 12:30:56 +0000</pubDate>
		<dc:creator>Sean</dc:creator>
		
		<category><![CDATA[Azure]]></category>

		<category><![CDATA[PDC 2008]]></category>

		<category><![CDATA[cloud]]></category>

		<category><![CDATA[Cloud service]]></category>

		<category><![CDATA[Microsoft PDC]]></category>

		<category><![CDATA[pdc08]]></category>

		<category><![CDATA[pdc2008]]></category>

		<category><![CDATA[Software+Services]]></category>

		<category><![CDATA[Windows Azure]]></category>

		<guid isPermaLink="false">http://spsexton.wordpress.com/?p=381</guid>
		<description><![CDATA[PDC 2008, Day #4, Session #1, 1 hr 30 mins
Gianpaolo Carraro
As the last day of PDC starts, I’m down to four sessions to go.  I’ll continue doing a quick blog post on each session, where I share my notes, as well as some miscellaneous thoughts.
The Idea of a Symposium
Gianpaolo started out by explaining that they [...]]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><em>PDC 2008, Day #4, Session #1, 1 hr 30 mins</em></p>
<p><em>Gianpaolo Carraro</em></p>
<p>As the last day of PDC starts, I’m down to four sessions to go.  I’ll continue doing a quick blog post on each session, where I share my notes, as well as some miscellaneous thoughts.</p>
<p><strong>The Idea of a Symposium</strong></p>
<p>Gianpaolo started out by explaining that they were finishing PDC by doing a pair of symposiums, each a series of three different sessions.  One symposium focused on parallel computing and the other on cloud-based services.  This particular session was the first in the set of three that addressed cloud services.</p>
<p>The idea of a symposium, explained Gianpaolo, is to take all of the various individual technologies and try to sort of fit the puzzle pieces together, providing a basic context.</p>
<p>The goal was also present some of the experience that Microsoft has gained in early usage of the Azure platform over the past 6-12 months.  He said that he himself has spent the last 6-12 months using the new Services, so he had some thoughts to share.</p>
<p>This first session in the symposium focused on taking existing business applications and expanding them to “the cloud”.  When should an ISV do this?  Why?  How?</p>
<p><strong>Build vs. Buy and On-Premises vs. Cloud</strong></p>
<p>Gianpaolo presented a nice matrix showing the two basic independent decisions that you face when looking for software to fulfill a need.</p>
<ul>
<li><strong>Build vs. Buy </strong>– Can I buy a packaged off-the-shelf product that does what I need?  Or are my needs specialized enough that I need to build my own stuff?</li>
<li><strong>On-Premises vs. Cloud </strong>– Should I run this software on my own servers?  Or host everything up in “the cloud”?</li>
</ul>
<p>There are, of course, tradeoffs on both sides of each decision.  These have been discussed ad infinitum elsewhere, but the basic tradeoffs are:</p>
<ul>
<li><strong>Build vs. Buy </strong>– Features vs. Cost</li>
<li><strong>On-Premises vs. Cloud </strong>– Control vs. Economy of Scale</li>
</ul>
<p>Here’s the graph that Gianpaolo presented, showing six different classes of software, based on how you answer these questions.  Note that on the On-Premises vs. Cloud scale, there is a middle column that represents taking applications that you essentially control and moving them to co-located servers.</p>
<p><a href="http://spsexton.files.wordpress.com/2008/11/1-1-matrix.jpg"><img class="alignnone size-full wp-image-383" title="1-1-matrix" src="http://spsexton.files.wordpress.com/2008/11/1-1-matrix.jpg?w=778&#038;h=330" alt="" width="778" height="330" /></a></p>
<p>This is a nice way to look at things.  It shows that, for each individual software function, it can live anywhere on this graph.  In fact, Gianpaolo’s main point is that you can deploy different pieces of your solution at different spots on the graph.</p>
<p>So the idea is that while you might start off on-premises, you can push your so