<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.claritycon.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>blogs.claritycon.com</title><link>http://blogs.claritycon.com/blogs/</link><description /><dc:language>en-US</dc:language><generator>CommunityServer 2007.1 (Build: 20917.1142)</generator><item><title>tfs 2010 RC Agile Process template update – New Task progress report</title><link>http://blogs.claritycon.com/blogs/ryan_powers/archive/2010/03/12/tfs-2010-rc-agile-process-template-update-new-task-progress-report.aspx</link><pubDate>Fri, 12 Mar 2010 19:49:34 GMT</pubDate><guid isPermaLink="false">da947a97-509e-40e6-bbb5-1443ad47bf4e:116953</guid><dc:creator>rpowers</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;Maybe my next post will just be about why I am so excited and impressed with the out of the box templates.&amp;#160; But, for this first blog with my new focus, I thought I would just walk through the process I went through to create a task progress report (to enhance the out of the box Agile template).&lt;/p&gt;  &lt;p&gt;So, I started with the MSF for Agile Development 5.0 RC template.&amp;#160; After reviewing the template, I came away pretty excited about many of the new reports.&amp;#160; I am especially excited about the reporting services reports.&amp;#160; The big advantage I see here is that these are querying the Warehouse directly instead of the Analysis Services Cube which means that they are much closer to real-time which I find very important for reports like Burndown and task status.&amp;#160; One report that I focused on right away was the User Story Progress Report.&amp;#160; An overview is shown below:&lt;/p&gt;  &lt;p&gt;&lt;img alt="Example Stories Progress Report" src="http://i.msdn.microsoft.com/Dd380641.ProcGuid_RepStoriesProgress(en-us,VS.100).png" width="409" height="253" /&gt;&lt;/p&gt;  &lt;p&gt;This report is very useful, but a lot of our internal managers really prefer to manage at the task level and either don’t have stories in TFS or would like to view this type of report for tasks in addition to the User Stories.&amp;#160; So, what did I do?&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Step 1: Download the Agile Template&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;In VS 2010 RC, open Process Template Manager from Team-&amp;gt;Team Project Collection Settings.&amp;#160; Download the MSF for Agile Development template to your local file system.&amp;#160; A project template is a folder of xml files.&amp;#160; There is a ProcessTemplate.xml in the root and then a bunch of directories for things like Work Item Definitions and Queries, Reports, Shared Documents and Source Control Settings.&amp;#160; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.claritycon.com/blogs/ryan_powers/image_02CB5D1A.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" border="0" alt="image" src="http://blogs.claritycon.com/blogs/ryan_powers/image_thumb_4295439F.png" width="400" height="281" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Step 2: Copy the folder &lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;My plan here is to make a new template with all of my modifications.&amp;#160; You can also just enhance update the MSF template.&amp;#160; However, I think it is cleaner when you start making modifications to make your own template.&amp;#160; So, copy the folder and name it with your new template name.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Step 3: Change Template Name&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Open ProcessTemplate.xml and change the &amp;lt;name&amp;gt; of the template.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Step 4: Copy the rdl of the Report you want to use a starting point&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;In my case, I copied Stories Progress.rdl and named the file Task Progress Breakdown.rdl.&amp;#160; I reviewed the requirements for the new report with some of the users here and came up with this plan.&amp;#160; Should show tasks and be expandable to show subtasks.&amp;#160; Should add Assigned To and Estimated Finish Date as 2 extra columns.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Step 5: Walkthrough the existing report to understand how it works&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The main thing that I do here is try to get the sql to run in SQL Management Studio.&amp;#160; So, I can walkthrough the process of building up the data for the report. &lt;/p&gt;  &lt;p&gt;After analyzing this particular report I found a couple of very useful things.&amp;#160; One, this report is already built to display subtasks if I just flip the IncludeTasks flag to 1.&amp;#160; So, if you are using Stories and have tasks assigned to each story.&amp;#160; This might give you everything you want.&amp;#160; &lt;/p&gt;  &lt;p&gt;For my purposes, I did make that change to the Stories Progress report as I find it to be a more useful report to be able to see the tasks that comprise each story.&amp;#160; But, I still wanted a task only version with the additional fields.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Step 6: Update the report definition&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;I tend to work on rdl in visual studio directly as xml.&amp;#160; Especially when I am just altering an existing report, I find it easier than trying to deal with the BI Studio designer.&amp;#160; For my report I made the following changes.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Updated Fields      &lt;ul&gt;       &lt;li&gt;Removed Stack Rank and Replaced with Priority since we don’t use Stack Rank &lt;/li&gt;        &lt;li&gt;Added FinishDate and AssignedTo &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;Changed the root deliverable SQL to pull @tasks instead of @deliverablecategory and added a join CurrentWorkItemView for FinishDate and Assigned to &lt;/li&gt; &lt;/ul&gt;  &lt;blockquote&gt;   &lt;div class="code"&gt;&lt;font color="#0000ff"&gt;SELECT&lt;/font&gt;&lt;font color="#808080"&gt;&amp;#160;&lt;/font&gt;&lt;font color="#000000"&gt;cwi.[System_Id]&lt;/font&gt;&lt;font color="#808080"&gt;&amp;#160;&lt;/font&gt;&lt;font color="#0000ff"&gt;AS&lt;/font&gt;&lt;font color="#808080"&gt;&amp;#160;&lt;/font&gt;&lt;font color="#0000ff"&gt;ID&lt;/font&gt;&lt;font color="#808080"&gt;&amp;#160;&lt;/font&gt;&lt;font color="#0000ff"&gt;FROM&lt;/font&gt;&lt;font color="#808080"&gt;&amp;#160;&lt;/font&gt;&lt;font color="#000000"&gt;[CurrentWorkItemView]&lt;/font&gt;&lt;font color="#808080"&gt;&amp;#160;&lt;/font&gt;&lt;font color="#000000"&gt;cwi&lt;/font&gt;&lt;font color="#808080"&gt;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#0000ff"&gt;WHERE&lt;/font&gt;&lt;font color="#808080"&gt;&amp;#160;&lt;/font&gt;&lt;font color="#000000"&gt;cwi.[System_WorkItemType]&lt;/font&gt;&lt;font color="#808080"&gt;&amp;#160;&lt;/font&gt;&lt;font color="#0000ff"&gt;IN&lt;/font&gt;&lt;font color="#808080"&gt;&amp;#160;&lt;/font&gt;&lt;font color="#000000"&gt;(@Task)&lt;/font&gt;&lt;font color="#808080"&gt;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#0000ff"&gt;AND&lt;/font&gt;&lt;font color="#808080"&gt;&amp;#160;&lt;/font&gt;&lt;font color="#000000"&gt;cwi.[ProjectNodeGUID]&lt;/font&gt;&lt;font color="#808080"&gt;&amp;#160;&lt;/font&gt;&lt;font color="#0000ff"&gt;=&lt;/font&gt;&lt;font color="#808080"&gt;&amp;#160;&lt;/font&gt;&lt;font color="#000000"&gt;@ProjectGuid&lt;/font&gt; &lt;/div&gt;    &lt;div class="code"&gt;&lt;font color="#0000ff"&gt;&lt;/font&gt;&lt;/div&gt;    &lt;div class="code"&gt;&lt;font color="#0000ff"&gt;SELECT&lt;/font&gt;&lt;font color="#808080"&gt;&amp;#160;&lt;/font&gt;&lt;font color="#000000"&gt;lh.SourceWorkItemID&lt;/font&gt;&lt;font color="#808080"&gt;&amp;#160;&lt;/font&gt;&lt;font color="#0000ff"&gt;AS&lt;/font&gt;&lt;font color="#808080"&gt;&amp;#160;&lt;/font&gt;&lt;font color="#0000ff"&gt;ID&lt;/font&gt;&lt;font color="#808080"&gt;&amp;#160;&lt;/font&gt;&lt;font color="#0000ff"&gt;FROM&lt;/font&gt;&lt;font color="#808080"&gt;&amp;#160;&lt;/font&gt;&lt;font color="#000000"&gt;FactWorkItemLinkHistory&lt;/font&gt;&lt;font color="#808080"&gt;&amp;#160;&lt;/font&gt;&lt;font color="#000000"&gt;lh&lt;/font&gt;&lt;font color="#808080"&gt;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#0000ff"&gt;INNER&lt;/font&gt;&lt;font color="#808080"&gt;&amp;#160;&lt;/font&gt;&lt;font color="#0000ff"&gt;JOIN&lt;/font&gt;&lt;font color="#808080"&gt;&amp;#160;&lt;/font&gt;&lt;font color="#000000"&gt;[CurrentWorkItemView]&lt;/font&gt;&lt;font color="#808080"&gt;&amp;#160;&lt;/font&gt;&lt;font color="#000000"&gt;cwi&lt;/font&gt;&lt;font color="#808080"&gt;&amp;#160;&lt;/font&gt;&lt;font color="#0000ff"&gt;ON&lt;/font&gt;&lt;font color="#808080"&gt;&amp;#160;&lt;/font&gt;&lt;font color="#000000"&gt;lh.TargetWorkItemID&lt;/font&gt;&lt;font color="#808080"&gt;&amp;#160;&lt;/font&gt;&lt;font color="#0000ff"&gt;=&lt;/font&gt;&lt;font color="#808080"&gt;&amp;#160;&lt;/font&gt;&lt;font color="#000000"&gt;cwi.[System_Id]&lt;/font&gt;&lt;font color="#808080"&gt;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#0000ff"&gt;WHERE&lt;/font&gt;&lt;font color="#808080"&gt;&amp;#160;&lt;/font&gt;&lt;font color="#000000"&gt;lh.WorkItemLinkTypeSK&lt;/font&gt;&lt;font color="#808080"&gt;&amp;#160;&lt;/font&gt;&lt;font color="#0000ff"&gt;=&lt;/font&gt;&lt;font color="#808080"&gt;&amp;#160;&lt;/font&gt;&lt;font color="#000000"&gt;@ParentWorkItemLinkTypeSK&lt;/font&gt;&lt;font color="#808080"&gt;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#0000ff"&gt;AND&lt;/font&gt;&lt;font color="#808080"&gt;&amp;#160;&lt;/font&gt;&lt;font color="#000000"&gt;lh.RemovedDate&lt;/font&gt;&lt;font color="#808080"&gt;&amp;#160;&lt;/font&gt;&lt;font color="#0000ff"&gt;=&lt;/font&gt;&lt;font color="#808080"&gt;&amp;#160;&lt;/font&gt;&lt;font color="#0000ff"&gt;CONVERT&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#0000ff"&gt;DATETIME&lt;/font&gt;&lt;font color="#000000"&gt;,&lt;/font&gt;&lt;font color="#808080"&gt; &amp;#39;9999&amp;#39;&lt;/font&gt;&lt;font color="#000000"&gt;,&lt;/font&gt;&lt;font color="#808080"&gt;&amp;#160;&lt;/font&gt;&lt;font color="#800000"&gt;126&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#808080"&gt;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#0000ff"&gt;AND&lt;/font&gt;&lt;font color="#808080"&gt;&amp;#160;&lt;/font&gt;&lt;font color="#000000"&gt;lh.TeamProjectCollectionSK&lt;/font&gt;&lt;font color="#808080"&gt;&amp;#160;&lt;/font&gt;&lt;font color="#0000ff"&gt;=&lt;/font&gt;&lt;font color="#808080"&gt;&amp;#160;&lt;/font&gt;&lt;font color="#000000"&gt;@TeamProjectCollectionSK&lt;/font&gt;&lt;font color="#808080"&gt;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#0000ff"&gt;AND&lt;/font&gt;&lt;font color="#808080"&gt;&amp;#160;&lt;/font&gt;&lt;font color="#000000"&gt;cwi.[System_WorkItemType]&lt;/font&gt;&lt;font color="#808080"&gt;&amp;#160;&lt;/font&gt;&lt;font color="#0000ff"&gt;NOT&lt;/font&gt;&lt;font color="#808080"&gt;&amp;#160;&lt;/font&gt;&lt;font color="#0000ff"&gt;IN&lt;/font&gt;&lt;font color="#808080"&gt;&amp;#160;&lt;/font&gt;&lt;font color="#000000"&gt;(@DeliverableCategory)&lt;/font&gt; &lt;/div&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Added AssignedTo and FinishDate columns to the @Rollups table &lt;/li&gt;    &lt;li&gt;Added two columns to the table used for column headers &lt;/li&gt; &lt;/ul&gt;  &lt;div class="code"&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000"&gt;Tablix&lt;/font&gt;&lt;font color="#ff0000"&gt; Name&lt;/font&gt;&lt;font color="#0000ff"&gt;=&amp;quot;ProgressTable&amp;quot;&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000"&gt;TablixBody&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000"&gt;TablixColumns&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000"&gt;TablixColumn&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000"&gt;Width&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;2.7625in&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#800000"&gt;Width&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#800000"&gt;TablixColumn&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000"&gt;TablixColumn&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000"&gt;Width&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;0.5125in&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#800000"&gt;Width&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#800000"&gt;TablixColumn&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000"&gt;TablixColumn&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000"&gt;Width&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;3.4625in&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#800000"&gt;Width&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#800000"&gt;TablixColumn&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000"&gt;TablixColumn&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000"&gt;Width&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;0.7625in&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#800000"&gt;Width&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#800000"&gt;TablixColumn&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;      &lt;br /&gt;&lt;/font&gt;&lt;font color="#008000"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;TablixColumn&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Width&amp;gt;1.25in&amp;lt;/Width&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/TablixColumn&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;TablixColumn&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Width&amp;gt;1.25in&amp;lt;/Width&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#800000"&gt;TablixColumn&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#800000"&gt;TablixColumns&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;&lt;/font&gt; &lt;/div&gt;  &lt;ul&gt;   &lt;li&gt;     &lt;div class="code"&gt;Added Cells for the two new headers&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div class="code"&gt;Added Cells to the data table to include the two new values (Assigned to &amp;amp; Finish Date)&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div class="code"&gt;Changed a bunch of widths that would change the format of the report to display landscape and have room for the two additional columns&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div class="code"&gt;Set the Value of the IncludeTasks Parameter to 1&lt;/div&gt;      &lt;div class="code"&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000"&gt;ReportParameter&lt;/font&gt;&lt;font color="#ff0000"&gt; Name&lt;/font&gt;&lt;font color="#0000ff"&gt;=&amp;quot;IncludeTasks&amp;quot;&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;          &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000"&gt;DataType&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;Integer&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#800000"&gt;DataType&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;          &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000"&gt;DefaultValue&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;          &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000"&gt;Values&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;          &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000"&gt;Value&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;=1&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#800000"&gt;Value&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;          &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#800000"&gt;Values&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;          &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#800000"&gt;DefaultValue&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;          &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000"&gt;Prompt&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;IncludeTasks&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#800000"&gt;Prompt&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;          &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000"&gt;Hidden&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;true&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#800000"&gt;Hidden&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;          &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#800000"&gt;ReportParameter&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;&lt;/font&gt; &lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div class="code"&gt;Change a few descriptions on how the report should be used&lt;/div&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p class="code"&gt;This is the resulting report&lt;/p&gt;  &lt;p class="code"&gt;&lt;a href="http://blogs.claritycon.com/blogs/ryan_powers/image_5B9113E4.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" border="0" alt="image" src="http://blogs.claritycon.com/blogs/ryan_powers/image_thumb_227A36E2.png" width="639" height="314" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p class="code"&gt;I have attached the final &lt;a href="http://employees.claritycon.com/rpowers/blog/TaskProgressBreakdown.zip"&gt;rdl&lt;/a&gt;. &lt;/p&gt;  &lt;p class="code"&gt;&lt;strong&gt;Step 7: Update ReportTasks.xml&lt;/strong&gt;&lt;/p&gt;  &lt;p class="code"&gt;Last step before the template is ready for use is to update the reportTasks.xml file in the reports folder.&amp;#160; This file defines the reports that are available in the template.&lt;/p&gt;  &lt;div class="code"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000"&gt;report&lt;/font&gt;&lt;font color="#ff0000"&gt; name&lt;/font&gt;&lt;font color="#0000ff"&gt;=&amp;quot;Task Progress Breakdown&amp;quot;&lt;/font&gt;&lt;font color="#ff0000"&gt; filename&lt;/font&gt;&lt;font color="#0000ff"&gt;=&amp;quot;Reports\Task Progress Breakdown.rdl&amp;quot;&lt;/font&gt;&lt;font color="#ff0000"&gt; folder&lt;/font&gt;&lt;font color="#0000ff"&gt;=&amp;quot;Project Management&amp;quot;&lt;/font&gt;&lt;font color="#ff0000"&gt; cacheExpiration&lt;/font&gt;&lt;font color="#0000ff"&gt;=&amp;quot;30&amp;quot;&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000"&gt;parameters&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000"&gt;parameter&lt;/font&gt;&lt;font color="#ff0000"&gt; name&lt;/font&gt;&lt;font color="#0000ff"&gt;=&amp;quot;ExplicitProject&amp;quot;&lt;/font&gt;&lt;font color="#ff0000"&gt; value&lt;/font&gt;&lt;font color="#0000ff"&gt;=&amp;quot;&amp;quot;&lt;/font&gt;&lt;font color="#ff0000"&gt;&amp;#160;&lt;/font&gt;&lt;font color="#0000ff"&gt;/&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/&lt;/font&gt;&lt;font color="#800000"&gt;parameters&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000"&gt;datasources&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000"&gt;reference&lt;/font&gt;&lt;font color="#ff0000"&gt; name&lt;/font&gt;&lt;font color="#0000ff"&gt;=&amp;quot;/Tfs2010ReportDS&amp;quot;&lt;/font&gt;&lt;font color="#ff0000"&gt; dsname&lt;/font&gt;&lt;font color="#0000ff"&gt;=&amp;quot;TfsReportDS&amp;quot;&lt;/font&gt;&lt;font color="#ff0000"&gt;&amp;#160;&lt;/font&gt;&lt;font color="#0000ff"&gt;/&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/&lt;/font&gt;&lt;font color="#800000"&gt;datasources&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#800000"&gt;report&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;&lt;/font&gt; &lt;/div&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Step 8: Upload the template&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Open the process Template Manager just like Step 1.&amp;#160; And upload the new template.&lt;/p&gt;  &lt;p&gt;That’s it.&amp;#160; One other note, if you want to add this report to existing team project you will have to go into reportmanager (the reporting services portal) and upload the rdl to that projects directory.&lt;/p&gt;&lt;img src="http://blogs.claritycon.com/aggbug.aspx?PostID=116953" width="1" height="1"&gt;</description></item><item><title>Blog Rebranding</title><link>http://blogs.claritycon.com/blogs/ryan_powers/archive/2010/03/12/blog-rebranding.aspx</link><pubDate>Fri, 12 Mar 2010 17:20:51 GMT</pubDate><guid isPermaLink="false">da947a97-509e-40e6-bbb5-1443ad47bf4e:116950</guid><dc:creator>rpowers</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;I have been spending more and more time on learning as much as I can on Agile Development and also have been fairly immersed in rolling out TFS 2010 in our environment.&amp;#160; I feel like it is time to talk about some of my experiences.&amp;#160; With that, I am rebranding my blog to focus on these topics.&amp;#160; I am going to start with a bunch of blogs on the process I have gone through getting TFS 2010 configured for our development teams.&lt;/p&gt;  &lt;p&gt;Last week, Brian Harry was in our office and gave a great talk on the improved tools in TFS 2010 and how Microsoft uses the tools internally.&amp;#160; I followed that up with a high-level overview of the improved out of the box process templates and the process to customize them.&amp;#160; I am definitely very excited about the new features in 2010 and hopefully will keep up my motivation to blog about it.&amp;#160; I am writing my first post right now about the process I went through to build a task progress report based on the user story progress report in the MSF for Agile Development template.&amp;#160; Stay tuned…&lt;/p&gt;&lt;img src="http://blogs.claritycon.com/aggbug.aspx?PostID=116950" width="1" height="1"&gt;</description></item><item><title>Building KPIs to monitor your business – It’s not really about the Technology</title><link>http://blogs.claritycon.com/blogs/andrew_karcher/archive/2010/03/08/building-kpis-to-monitor-your-business-it-s-not-really-about-the-technology.aspx</link><pubDate>Tue, 09 Mar 2010 07:47:05 GMT</pubDate><guid isPermaLink="false">da947a97-509e-40e6-bbb5-1443ad47bf4e:116378</guid><dc:creator>akarcher</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;When I have discussions with people about Business Intelligence, one of the questions the inevitably come up is about building KPIs and how to accomplish that. From a technical level the concept of a KPI is very simple, almost too simple in that it is like the tip of an iceberg floating above the water. The key to that iceberg is not really the tip, but the mass of the iceberg that is hidden beneath the surface upon which the tip sits.&lt;/p&gt;  &lt;p&gt;The analogy of the iceberg is not meant to indicate that the foundation of the KPI is overly difficult or complex. The disparity in size in meant to indicate that the larger thing that needs to be defined is not the technical tip, but the underlying business definition of what the KPI means. From a technical perspective the KPI consists of primarily the following items:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Actual Value – This is the actual value data point that is being measured. An example would be something like the amount of sales.&lt;/li&gt;    &lt;li&gt;Target Value – This is the target goal for the KPI. This is a number that can be measured against Actual Value. An example would be $10,000 in monthly sales.&lt;/li&gt;    &lt;li&gt;Target Indicator Range – This is the definition of ranges that define what type of indicator the user will see comparing the Actual Value to the Target Value. Most often this is defined by stoplight, but can be any indicator that is going to show a status in a quick fashion to the user. Typically this would be something like: Red Light = Actual Value more than 5% below target; Yellow Light = Within 5% of target either direction; Green Light = More than 5% higher than Target Value&lt;/li&gt;    &lt;li&gt;Status\Trend Indicator – This is an optional attribute of a KPI that is typically used to show some kind of trend. The vast majority of these indicators are used to show some type of progress against a previous period. As an example, the status indicator might be used to show how the monthly sales compare to last month. With this type of indicator there needs to be not only a definition of what the ranges are for your status indictor, but then also what value the number needs to be compared against.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;So now we have an idea of what data points a KPI consists of from a technical perspective let’s talk a bit about tools. As you can see technically there is not a whole lot to them and the choice of technology is not as important as the definition of the KPIs, which we will get to in a minute. There are many different types of tools in the Microsoft BI stack that you can use to expose your KPI to the business. These include Performance Point, SharePoint, Excel, and SQL Reporting Services. There are pluses and minuses to each technology and the right technology is based a lot on your goals and how you want to deliver the information to the users. Additionally, there are other non-Microsoft tools that can be used to expose KPI indicators to your business users.&lt;/p&gt;  &lt;p&gt;Regardless of the technology used as your front end, the heavy lifting of KPI is in the business definition of the values and benchmarks for that KPI. The discussion about KPIs is very dependent on the history of an organization and how much they are exposed to the attributes of a KPI. Often times when discussing KPIs with a business contact who has not been exposed to KPIs the discussion tends to also be a session educating the business user about what a KPI is and what goes into the definition of a KPI. The majority of times the business user has an idea of what their actual values are and they have been tracking those numbers for some time, generally in Excel and all manually. So they will know the amount of sales last month along with sales two years ago in the same month. Where the conversation tends to get stuck is when you start discussing what the target value should be.&lt;/p&gt;  &lt;p&gt;The actual value is answering the “What” and “How much” questions. When you are talking about the Target values you are asking the question “Is this number good or bad”. Typically, the user will know whether or not the value is good or bad, but most of the time they are not able to quantify what is good or bad. Their response is usually something like “I just know”. Because they have been watching the sales quantity for years now, they can tell you that a 5% decrease in sales this month might actually be a good thing, maybe because the salespeople are all waiting until next month when the new versions come out.&lt;/p&gt;  &lt;p&gt;It can sometimes be very hard to break the business people of this habit. One of the fears generally is that the status indicator is not subjective. Thus, in the scenario above, the business user is going to be fearful that their boss, just looking at a negative red indicator, is going to haul them out to the woodshed for a bad month. But, on the flip side, if all you are displaying is the amount of sales, only a person with knowledge of last month sales and the target amount for this month would have any idea if $10,000 in sales is good or not.&lt;/p&gt;  &lt;p&gt;Here is where a key point about KPIs needs to be communicated to both the business user and any user who might be viewing the results of that KPI. The KPI is just one tool that is used to report on business performance. The KPI is meant as a quick indicator of one business statistic. It is not meant to tell the entire story. It does not answer the question “Why”. Its primary purpose is to objectively and quickly expose an area of the business that might warrant more review. There is always going to be the need to do further analysis on any potential negative or neutral KPI.&lt;/p&gt;  &lt;p&gt;So, hopefully, once you have convinced your business user to come up with some target numbers and ranges for status indicators, you then need to take the next step and help them answer the “Why” question. The main question here to ask is, “Okay, you see the indicator and you need to discover why the number is what is, where do you go?”. The answer is usually a combination of sources. A sales manager might have some of the following items at their disposal (Marketing report showing a decrease in the promotional discounts for the month, Pricing Report showing the reduction of prices of older models, an Inventory Report showing the discontinuation of a particular product line, or a memo showing the ending of a large affiliate partnership. The answers to the question “Why” are never as simple as a single indicator value.&lt;/p&gt;  &lt;p&gt;Bring able to quickly get to this information is all about designing how a user accesses the KPIs and then also how easily they can get to the additional information they need. This is where a Dashboard mentality can come in handy. For example, the business user can have a dashboard that shows their KPIs, but also has links to some of the common reports that they run regarding Sales Data. The user’s boss may have the same KPIs on their dashboard, but instead of links to individual reports they are going to have a link to a status report that was created by the user that pulls together all the data about the KPI in a summary format the user’s boss can review.&lt;/p&gt;  &lt;p&gt;So some of the key things to think about when building or evaluating KPIs for your organization:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Technology should not be the driving factor&lt;/li&gt;    &lt;li&gt;KPIs are of little value without some indicator for whether a value is good, bad or neutral.&lt;/li&gt;    &lt;li&gt;KPIs only give an answer to the “Is this number good\bad?” question&lt;/li&gt;    &lt;li&gt;Make sure the ability to drill into the “Why” of a KPI is close at hand and relevant to the user who is viewing the KPI.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The KPI is a key business tool when defined properly to help monitor business performance across the enterprise in an objective and consistent manner. At times it might feel like the process of defining the business aspects of a KPI can sometimes be arduous, the payoff in the end can far outweigh the costs. Some of the benefits of going through this process are a better understanding of the key metrics for an organization and the measure of those metrics and a consistent snapshot of business performance that can be utilized across the organization. And I think that these are benefits to any organization regardless of the technology or the implementation.&lt;/p&gt;&lt;img src="http://blogs.claritycon.com/aggbug.aspx?PostID=116378" width="1" height="1"&gt;</description></item><item><title>Invisible OCS conference participants</title><link>http://blogs.claritycon.com/blogs/michael_greenlee/archive/2010/02/21/invisible-ocs-conference-participants.aspx</link><pubDate>Sun, 21 Feb 2010 19:18:34 GMT</pubDate><guid isPermaLink="false">da947a97-509e-40e6-bbb5-1443ad47bf4e:114101</guid><dc:creator>mgreenlee</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;&lt;img title="invisible" style="border-right:0px;border-top:0px;display:inline;margin-left:0px;border-left:0px;margin-right:0px;border-bottom:0px;" height="331" alt="invisible" src="http://blogs.claritycon.com/blogs/michael_greenlee/invisible_1397732F.jpg" width="277" align="right" border="0" /&gt; Many of you, since encountering OCS 2007 R2 and its trusty sidekick server-side API, UCMA 2.0, have been wondering, “How do I spy on people and secretly record their audio conferences?” &lt;/p&gt;  &lt;p&gt;Luckily for you, to complement its delightfully straightforward automation of SIP messaging, UCMA 2.0 has a rich array of covert operations functionality.&lt;/p&gt;  &lt;p&gt;That may be a slight exaggeration. What it does provide is a way for server-side applications to perform a “trusted conference join.” A UCMA 2.0 application running as a trusted service which has authenticated with the OCS server by means of a certificate can join a conference invisibly, meaning it does not show up in the roster of conference participants.&lt;/p&gt;  &lt;p&gt;Although I was tempted to title this article “Wiretapping in UCMA 2.0,” the trusted conference join feature has many uses. It allows you to create applications that provide services to OCS conferences without causing distracting and tacky-looking bots to appear in the list of participants. Some examples:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Recording conversations for auditing, monitoring, or training purposes &lt;/li&gt;    &lt;li&gt;Conference timekeeping for businesses that bill by the minute &lt;/li&gt;    &lt;li&gt;Piping music or audio announcements into a conference &lt;/li&gt;    &lt;li&gt;Silent monitoring of conferences for training purposes &lt;/li&gt;    &lt;li&gt;Scaring people in a conference by suddenly saying something when they didn’t know you were there &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;So how do you do it?&lt;/p&gt;  &lt;p&gt;First of all, your application needs to be using an application endpoint rather than a user endpoint. User endpoints cannot join conferences as a trusted participant.&lt;/p&gt;  &lt;p&gt;When you call the &lt;em&gt;BeginJoin&lt;/em&gt; method on the &lt;em&gt;ConferenceSession&lt;/em&gt; object to join a conference, you can supply a &lt;em&gt;ConferenceJoinInformation&lt;/em&gt; object with the URI of the conference you want to join. This &lt;em&gt;ConferenceJoinInformation&lt;/em&gt; object also has a property called &lt;em&gt;IsTrustedJoin&lt;/em&gt;. When this property is set to true, your application endpoint will join the conference as a trusted participant.&lt;/p&gt;  &lt;p&gt;Let’s say you are joining a conference that has already started, and you have the conference URI stored in a local variable. You would do something like this:&lt;/p&gt;   &lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;// Create a ConferenceJoinInformation object with the conference URI&lt;/span&gt;
ConferenceJoinInformation joinInfo = &lt;span class="kwrd"&gt;new&lt;/span&gt; ConferenceJoinInformation(
    &lt;span class="kwrd"&gt;new&lt;/span&gt; Microsoft.Rtc.Signaling.RealTimeAddress(conferenceUri)
);

&lt;span class="rem"&gt;// Make this a trusted join&lt;/span&gt;
joinInfo.IsTrustedJoin = &lt;span class="kwrd"&gt;true&lt;/span&gt;;

&lt;span class="rem"&gt;// Create a new conversation &lt;/span&gt;
conversation = &lt;span class="kwrd"&gt;new&lt;/span&gt; Conversation(_applicationEndpoint);

&lt;span class="rem"&gt;// USe the conversation to join the conference&lt;/span&gt;
conversation.ConferenceSession.BeginJoin(joinInfo,
    result =&amp;gt;
    {
        conversation.ConferenceSession.EndJoin(result);
    },
    &lt;span class="kwrd"&gt;null&lt;/span&gt;
);&lt;/pre&gt;

&lt;p&gt;First, you create a new instance of &lt;em&gt;ConferenceJoinInformation&lt;/em&gt;, passing in the conference URI. In order for the constructor to like it, you need to turn the string that contains the URI into a &lt;em&gt;RealTimeAddress&lt;/em&gt; object.&lt;/p&gt;

&lt;p&gt;Next, you set the &lt;em&gt;IsTrustedJoin&lt;/em&gt; property to true.&lt;/p&gt;

&lt;p&gt;Finally, you create a new conversation and call the &lt;em&gt;BeginJoin&lt;/em&gt; method, passing in the join information.&lt;/p&gt;

&lt;p&gt;When the asynchronous operation completes, your application will be a participant in the conference, sending and receiving media like any other, but it will be INVISIBLE.&lt;/p&gt;

&lt;p&gt;There is one other point I want to call out here before concluding. If you want to have more than one of these invisible participants from the same application (e.g. one to record and one to make animal noises) you can do this, on two conditions: you will need to create a &lt;em&gt;Conversation&lt;/em&gt; object for each participant, and you will need to impersonate a fake URI so that the participants have different URIs. &lt;/p&gt;

&lt;p&gt;To do this, you use the &lt;em&gt;Impersonate&lt;/em&gt; method on the &lt;em&gt;Conversation&lt;/em&gt; object, as below:&lt;/p&gt;


&lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;// Create a new conversation with impersonation&lt;/span&gt;
conversation = &lt;span class="kwrd"&gt;new&lt;/span&gt; Conversation(_applicationEndpoint);
conversation.Impersonate(&lt;span class="str"&gt;&amp;quot;RandomSounds@____________.com&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;tel:+15555551212&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;Random Sounds&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

&lt;p&gt;The URI you use can be completely fabricated; it doesn’t need to be a real contact. &lt;/p&gt;

&lt;p&gt;This technique can be especially handy when combined with a back-to-back user agent (B2BUA) to proxy remote users into a conference invisibly. More on this in a future post if there is interest.&lt;/p&gt;

&lt;p&gt;I take no responsibility for any imprudent or illegal things you do with trusted conference participants!&lt;/p&gt;&lt;img src="http://blogs.claritycon.com/aggbug.aspx?PostID=114101" width="1" height="1"&gt;</description></item><item><title>Putting Down Time</title><link>http://blogs.claritycon.com/blogs/peter_miller/archive/2010/02/20/putting-down-time.aspx</link><pubDate>Sun, 21 Feb 2010 04:43:29 GMT</pubDate><guid isPermaLink="false">da947a97-509e-40e6-bbb5-1443ad47bf4e:114030</guid><dc:creator>pmiller</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;In my last post I discussed how some creative thinking on my part led me to redo large chunks of a task scheduling library. As promised, here are some of the major changes and what I learned from them.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Lush Verbiage&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;In the refactor, I expanded upon the concept of a timekeeper and extended the metaphor to the rest of they component. So a timekeeper, keeps time, or in this case, a timetable. A timetable is composed of entries, a combination of time slot and actions scheduled for that time. A timekeeper has a worker which “works” the timetable using a simple procedure. Find the next entry in the timetable, keep track of the passage of time until it is past that entry’s time, execute the actions for that entry, find the next entry, continue on.&lt;/p&gt;  &lt;p&gt;The metaphor is strained at times, but by carefully choosing descriptive names for classes from the physical world, there was less mental friction when trying to implement or explain the component.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Design Simplicity&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Dealing with time based code in .NET is harder than it should be. Or more accurately, harder then I’d want it to be. Even the conceptually simple idea of scheduling a task to happen every hour is fraught with peril. I started with a Timer that went off at the next hour and repeated with a period of 60 minutes. This mostly works, but that timer will sometimes fire before the hour is up. Only a fraction of a second before the hour, but that is time enough to wreck havoc on logic that looks for the next event chronologically or on other components that depend on the hourly events occurring on or after the hour. If not havoc, at least make it messier. &lt;/p&gt;  &lt;p&gt;Ultimately, I could have gotten past that challenge, but I decided to simplify the code by making the main “tick” loop of the timekeeper (what looks for timetable entries that need to be executed) a brute force style thread.sleep, check, thread.sleep, check, loop. The idea of this approach grates on me as it is making the program spin more then it needs to, but a sleep of 100 ms was enough to not noticeably affect CPU utilization. In addition, this made it very easy to add support for a clean stop of the timekeeper worker:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;internal class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;TimekeeperWorker &lt;/span&gt;: &lt;span style="color:#2b91af;"&gt;BackgroundWorker
    &lt;/span&gt;{...&lt;/pre&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;protected override void &lt;/span&gt;OnDoWork(&lt;span style="color:#2b91af;"&gt;DoWorkEventArgs &lt;/span&gt;e)
{...&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;while &lt;/span&gt;(!CancellationPending)
          {
              &lt;span style="color:#2b91af;"&gt;Thread&lt;/span&gt;.Sleep(100);&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;blockquote style="margin-right:0px;" dir="ltr"&gt;
  &lt;p&gt;… “tick” loop logic&lt;/p&gt;

  &lt;p&gt;&amp;#160;&lt;/p&gt;

  &lt;pre class="code"&gt;}
           &lt;span style="color:green;"&gt;//cancellation pending, so exit out
           &lt;/span&gt;e.Cancel = &lt;span style="color:blue;"&gt;true&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre class="code"&gt;&amp;#160;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;Even after this latest refactor, there are more places I could simplify this code. However, just like optimization, there is an effort associated with simplification that isn’t always needed. At least not yet.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Daylight Savings Time&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is kind of a subset of Design Simplicity, but one of the concerns I had with this component was how it would handle Daylight Savings Time. When the clock jumps from 1:59AM to 1AM or 3AM for example. After some discussion with the team, the behavior we decided on was that in the case of jumping back, the timekeeper would fire the 1AM action twice, jumping forward, the timekeeper would fire the 3AM action, skipping any 2AM actions.&lt;/p&gt;

&lt;p&gt;With that expectation set, how to implement that? I debated using the TimeZone and TimeZoneInfo classes to get to the DaylightTime objects and figure that all out. After scratching my head over that for a while without making headway, I decided to again take a bit of a brute force approach in that timekeeper worker’s “tick” loop:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:#2b91af;"&gt;              Thread&lt;/span&gt;.Sleep(100);
              timeNow = &lt;span style="color:#2b91af;"&gt;TimekeeperClock&lt;/span&gt;.Now();
              &lt;span style="color:blue;"&gt;if &lt;/span&gt;( &lt;span style="color:#2b91af;"&gt;Math&lt;/span&gt;.Abs( (timeNow - lastTime).Ticks ) &amp;gt; &lt;span style="color:#2b91af;"&gt;TimeSpan&lt;/span&gt;.FromMinutes(1).Ticks)
              {
                  &lt;span style="color:green;"&gt;//if the time changes more then one minute (plus or minus)
                  //after a 1/10 of a second sleep, then
                  //we&amp;#39;ve had some kind of major clock adjustment &lt;br /&gt;                  //(potentially daylight savings time)
                  //so recalculate what the next entry would be
                  //have to back up the time a bit, in case it went from &lt;br /&gt;                  //1:59:59am to 3:00:01am on dst change
                  &lt;/span&gt;_logger.InfoFormat(&lt;span style="color:#a31515;"&gt;&amp;quot;Clock drift detected from {0} to {1} in one cycle.&amp;quot;&lt;/span&gt;,&lt;br /&gt;                       lastTime, timeNow);
                  &lt;span style="color:#2b91af;"&gt;DateTime &lt;/span&gt;lookBackTime = timeNow.Add(&lt;span style="color:#2b91af;"&gt;TimeSpan&lt;/span&gt;.FromMinutes(-1));
                  _logger.InfoFormat(&lt;span style="color:#a31515;"&gt;&amp;quot;Recalculating next entry based on a time of {0}&amp;quot;&lt;/span&gt;,&lt;br /&gt;                         lookBackTime);
                  _next = _timetable.GetNextEntry(lookBackTime);
              }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;The worker knows the last time it got from the clock, so if the next time it gets is significantly different, something has happened. The worker assumes it is a daylight savings time adjustment and recalculates the next timetable entry from the new time. In order to actually catch the hour changing, that next entry is actually calculated from the new time minus a minute. A bit goofy, but workable, and easier then dealing with the .NET time zone classes.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Testing Time&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Testing time based code is tough. I found it useful to just let the component run for days in our test environment and watch the log, but that’s not particularly efficient. So I wrote some automated tests for the timekeeper, for example, to test that the daylight savings time behavior was what I wanted:&lt;/p&gt;

&lt;pre class="code"&gt;[&lt;span style="color:#2b91af;"&gt;Test&lt;/span&gt;]
       &lt;span style="color:blue;"&gt;public void &lt;/span&gt;Should_Execute_One_AM_Task_Twice_On_Jump_Back_DST()
       {
           &lt;span style="color:blue;"&gt;var &lt;/span&gt;tt = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Timekeeper&lt;/span&gt;();
           &lt;span style="color:blue;"&gt;int &lt;/span&gt;numberTimesExecuted = 0;
           &lt;span style="color:blue;"&gt;var &lt;/span&gt;incrementTimesExecuted = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Task
           &lt;/span&gt;{
               Execute = dt =&amp;gt;
               {
                   numberTimesExecuted += 1;
                   &lt;span style="color:blue;"&gt;return new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;TaskResult &lt;/span&gt;{ Message = &lt;span style="color:#a31515;"&gt;&amp;quot;Incremented&amp;quot; &lt;/span&gt;};
               },
               FriendlyName = &lt;span style="color:#a31515;"&gt;&amp;quot;Increment Times Executed&amp;quot;
           &lt;/span&gt;};
           tt.ScheduleFor(&lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;TimeSpan&lt;/span&gt;(1,0,0), incrementTimesExecuted);
           &lt;span style="color:#2b91af;"&gt;TimekeeperClock&lt;/span&gt;.Now = () =&amp;gt; &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;DateTime&lt;/span&gt;(2010, 3, 14, 0, 59, 59);
           tt.Start();
           System.Threading.&lt;span style="color:#2b91af;"&gt;Thread&lt;/span&gt;.Sleep(200);&lt;span style="color:green;"&gt;//let timekeeper tick
           &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;TimekeeperClock&lt;/span&gt;.Now = () =&amp;gt; &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;DateTime&lt;/span&gt;(2010, 3, 14, 1, 0, 01);
           System.Threading.&lt;span style="color:#2b91af;"&gt;Thread&lt;/span&gt;.Sleep(200);&lt;span style="color:green;"&gt;//let timekeeper tick
           &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;TimekeeperClock&lt;/span&gt;.Now = () =&amp;gt; &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;DateTime&lt;/span&gt;(2010, 3, 14, 1, 59, 59);
           System.Threading.&lt;span style="color:#2b91af;"&gt;Thread&lt;/span&gt;.Sleep(200);&lt;span style="color:green;"&gt;//let timekeeper tick
           &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;TimekeeperClock&lt;/span&gt;.Now = () =&amp;gt; &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;DateTime&lt;/span&gt;(2010, 3, 14, 1, 0,01);
           System.Threading.&lt;span style="color:#2b91af;"&gt;Thread&lt;/span&gt;.Sleep(200);&lt;span style="color:green;"&gt;//let timekeeper tick
           &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Assert&lt;/span&gt;.AreEqual(2, numberTimesExecuted);
           tt.Stop();
       }

       [&lt;span style="color:#2b91af;"&gt;Test&lt;/span&gt;]
       &lt;span style="color:blue;"&gt;public void &lt;/span&gt;Should_Execute_One_AM_And_3_AM_And_Not_2_AM_Task_On_Jump_Forward_DST()
       {
           &lt;span style="color:blue;"&gt;var &lt;/span&gt;tt = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Timekeeper&lt;/span&gt;();
           &lt;span style="color:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt; hoursExecuted = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt;();
           &lt;span style="color:blue;"&gt;var &lt;/span&gt;addHourToExecuted = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Task
                                            &lt;/span&gt;{
                                                Execute = dt =&amp;gt;
                                                              {
                                                                  hoursExecuted.Add(dt.Hour);
                                                                  &lt;span style="color:blue;"&gt;return new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;TaskResult&lt;/span&gt;();
                                                              }
                                            };

           tt.ScheduleForEveryHour(addHourToExecuted);
           &lt;span style="color:#2b91af;"&gt;TimekeeperClock&lt;/span&gt;.Now = () =&amp;gt; &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;DateTime&lt;/span&gt;(2010, 3, 14, 0, 59, 59);
           tt.Start();
           System.Threading.&lt;span style="color:#2b91af;"&gt;Thread&lt;/span&gt;.Sleep(200);&lt;span style="color:green;"&gt;//let timekeeper tick
           &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;TimekeeperClock&lt;/span&gt;.Now = () =&amp;gt; &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;DateTime&lt;/span&gt;(2010, 3, 14, 1, 0, 01);
           System.Threading.&lt;span style="color:#2b91af;"&gt;Thread&lt;/span&gt;.Sleep(200);&lt;span style="color:green;"&gt;//let timekeeper tick
           &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;TimekeeperClock&lt;/span&gt;.Now = () =&amp;gt; &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;DateTime&lt;/span&gt;(2010, 3, 14, 1, 59, 59);
           System.Threading.&lt;span style="color:#2b91af;"&gt;Thread&lt;/span&gt;.Sleep(200);&lt;span style="color:green;"&gt;//let timekeeper tick
           &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;TimekeeperClock&lt;/span&gt;.Now = () =&amp;gt; &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;DateTime&lt;/span&gt;(2010, 3, 14, 3, 0, 01);
           System.Threading.&lt;span style="color:#2b91af;"&gt;Thread&lt;/span&gt;.Sleep(200);&lt;span style="color:green;"&gt;//let timekeeper tick
           &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Assert&lt;/span&gt;.Contains(1, hoursExecuted);
           &lt;span style="color:#2b91af;"&gt;Assert&lt;/span&gt;.Contains(3, hoursExecuted);
           &lt;span style="color:#2b91af;"&gt;Assert&lt;/span&gt;.False(hoursExecuted.Contains(2));
           tt.Stop();
       }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Pretty, these are certainly not. The lowlights include the numerous thread.sleep calls, which allow the timekeeper’s background worker to catch up and notice that the time has changed. The inline definition of tasks also ends up taking up a lot of screen real estate. Finally, the setting of method local variables from the action delegates seems clunky.&lt;/p&gt;

&lt;p&gt;With all that said, these tests do make me feel more confident that the timekeeper will behave as expected, and furthermore express the expected behavior of the component to anybody else who reads them. &lt;/p&gt;

&lt;p&gt;The reliance on using thread sleeps really bothers me; so far the only way around it that I could think of was to extract the main loop logic from worker into a pluggable algorithm, that is passed into the timekeeper as a dependency. Then I could test just that dependency in isolation. To put flesh on that, I’d have a property or constructor argument on the timekeeper that was an interface with a method that takes in the last known time, and a reference to the timetable, and then calculates what if anything to execute based on the current time.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Wrapping Up&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This has been fun for me, and fixing up this component will be valuable to my current project in helping us reduce our day to day support load. I also got more experience with unit testing, and some experience using git to put the code up on github. Hopefully you learned something along the way as well. If you think this code would be useful to you (or part of it), check it out at &lt;a href="http://github.com/phmiller/Timekeeper"&gt;http://github.com/phmiller/Timekeeper&lt;/a&gt;. And thanks for reading this far &amp;lt;g&amp;gt;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;--- Relevant Links ---&lt;/p&gt;

&lt;p&gt;The post wasn’t lengthy enough for you? Maybe try a dead-tree book, like Kent Beck’s XP Explained (2nd edition). Well worth your time:
  &lt;br /&gt;&lt;a href="http://www.amazon.com/Extreme-Programming-Explained-Embrace-Change/dp/0321278658/ref=dp_ob_title_bk"&gt;http://www.amazon.com/Extreme-Programming-Explained-Embrace-Change/dp/0321278658/ref=dp_ob_title_bk&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.claritycon.com/aggbug.aspx?PostID=114030" width="1" height="1"&gt;</description><category domain="http://blogs.claritycon.com/blogs/peter_miller/archive/tags/.NET/default.aspx">.NET</category></item><item><title>Brian Harry – Microsoft Technical Fellow – Speaking at Clarity Consulting</title><link>http://blogs.claritycon.com/blogs/george_durzi/archive/2010/02/18/brian-harry-microsoft-technical-fellow-speaking-at-clarity-consulting.aspx</link><pubDate>Fri, 19 Feb 2010 01:08:06 GMT</pubDate><guid isPermaLink="false">da947a97-509e-40e6-bbb5-1443ad47bf4e:113709</guid><dc:creator>gdurzi</dc:creator><slash:comments>1</slash:comments><description>&lt;p&gt;Join us on Thursday, March 4th from 3 pm - 6 pm for &lt;strong&gt;Visual Studio 2010 and Team Foundation Server 2010&lt;/strong&gt;, presented by Microsoft Technical Fellow, &lt;a href="http://blogs.msdn.com/bharry/"&gt;Brian Harry&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;Attend this event to learn more about Microsoft’s vision for developer team solutions.&amp;#160; Brian will cover the key advances for developers in Visual Studio 2010 and Team Foundation Server 2010.&lt;/p&gt;  &lt;p&gt;Attendees will have an opportunity to ask Brian Harry questions around Microsoft’s vision for developer tools and platforms.&amp;#160; This is a great opportunity to connect directly with a very senior and technical developer community leader within Microsoft.&lt;/p&gt;  &lt;p&gt;Ryan Powers from Clarity Consulting will also discuss how Clarity’s project teams use Team Foundation Server as part of the software development lifecycle. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032443618&amp;amp;Culture=en-US" target="_blank"&gt;Registration and more details&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://blogs.claritycon.com/aggbug.aspx?PostID=113709" width="1" height="1"&gt;</description></item><item><title>Time Again: Creative Destruction</title><link>http://blogs.claritycon.com/blogs/peter_miller/archive/2010/02/17/time-again-creative-destruction.aspx</link><pubDate>Thu, 18 Feb 2010 05:20:00 GMT</pubDate><guid isPermaLink="false">da947a97-509e-40e6-bbb5-1443ad47bf4e:113408</guid><dc:creator>pmiller</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;In the collection of interviews, &lt;em&gt;Coders At Work&lt;/em&gt;, a common theme was the idea that when confronted with a difficult debugging problem, it can be better to just redo the troubled code rather then fix it. &lt;/p&gt;  &lt;p&gt;&lt;img alt="File:Mansteel1.png" src="http://upload.wikimedia.org/wikipedia/en/5/53/Mansteel1.png" width="162" height="250" /&gt;&lt;/p&gt;  &lt;p&gt;This may seem like an invitation to put on your cape and do some hero-programming. This kind of creative destruction is only warranted when you are confident you can reproduce the functionality more coherently and with fewer bugs in less time than it would take to fully understand and tweak the existing code.&lt;/p&gt;  &lt;p&gt;As I mentioned in a previous post, I’ve been working on a component to keep time and schedule tasks. The basic requirements of which are:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Keep time in any time zone &lt;/li&gt;    &lt;li&gt;Provide a way to schedule tasks for every hour change, day change or arbitrary time &lt;/li&gt;    &lt;li&gt;Provide a mechanism to monitor the results of these tasks and/or any exceptions &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The implementation I described in that post mostly worked, but would occasionally just fall over in our test environment. I couldn’t find the bug and looking through the code, I saw a lot of room for improvement. So after some creative destruction, I had a new and cleaner implementation:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public interface &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ITimekeeper
  &lt;/span&gt;{
      &lt;span style="color:#2b91af;"&gt;Action&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;Exception&lt;/span&gt;&amp;gt; ExceptionHandler { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }
      &lt;span style="color:#2b91af;"&gt;Action&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;TaskResult&lt;/span&gt;&amp;gt; CompletedHandler { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }
      &lt;span style="color:blue;"&gt;void &lt;/span&gt;ScheduleFor(&lt;span style="color:#2b91af;"&gt;TimeSpan &lt;/span&gt;timeOfDay, &lt;span style="color:#2b91af;"&gt;Task &lt;/span&gt;task);
      &lt;span style="color:blue;"&gt;void &lt;/span&gt;ScheduleForEveryDay(&lt;span style="color:#2b91af;"&gt;Task &lt;/span&gt;task);
      &lt;span style="color:blue;"&gt;void &lt;/span&gt;ScheduleForEveryHour(&lt;span style="color:#2b91af;"&gt;Task &lt;/span&gt;task);
      &lt;span style="color:blue;"&gt;void &lt;/span&gt;Start();
      &lt;span style="color:blue;"&gt;void &lt;/span&gt;Stop();
  }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Task
   &lt;/span&gt;{
       &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;DateTime&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;TaskResult&lt;/span&gt;&amp;gt; Execute { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }
       &lt;span style="color:blue;"&gt;public string &lt;/span&gt;FriendlyName { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }
   }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;TaskResult
   &lt;/span&gt;{
       &lt;span style="color:blue;"&gt;public bool &lt;/span&gt;Error { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }
       &lt;span style="color:blue;"&gt;public string &lt;/span&gt;Message { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }
   }&lt;/pre&gt;

&lt;p&gt;Even just from a usage perspective this code reads much nicer to me:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;var &lt;/span&gt;tk = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Timekeeper&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;Central Standard Time&amp;quot;&lt;/span&gt;);&lt;br /&gt;tk.ScheduleForEveryHour(task1);
tk.ScheduleForEveryHour(task2);
tk.ExceptionHandler += &lt;br /&gt;  (task, ex) =&amp;gt; System.&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;br /&gt;      &lt;span style="color:#a31515;"&gt;&amp;quot;[Exception Handler] Exception for {0}: {1}&amp;quot;&lt;/span&gt;, &lt;br /&gt;      task.FriendlyName, ex);
tk.CompletedHandler += &lt;br /&gt;  (task, result) =&amp;gt; System.&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;br /&gt;      &lt;span style="color:#a31515;"&gt;&amp;quot;[Completed Handler] {0} completed with a message of {1}&amp;quot;&lt;/span&gt;, &lt;br /&gt;      task.FriendlyName,result.Message);
tk.Start();&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Under the hood, the changes were pervasive, and we’ll look at those changes in an upcoming post. 
  &lt;br /&gt;&lt;/p&gt;

&lt;p&gt;--- Relevant Links ---&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Coders At Work&lt;/em&gt; was a fascinating read for the insights into how some of the giants of our field work. The homepage is also notable for an excellent salmon background: 

  &lt;br /&gt;&lt;a href="http://www.codersatwork.com/"&gt;Coders At Work Homepage&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Can’t wait for the next post? Want to take a look at the code for yourself? View at your own risk: 
  &lt;br /&gt;&lt;a href="http://github.com/phmiller/Timekeeper"&gt;Timekeeper on Github&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.claritycon.com/aggbug.aspx?PostID=113408" width="1" height="1"&gt;</description><category domain="http://blogs.claritycon.com/blogs/peter_miller/archive/tags/.NET/default.aspx">.NET</category></item><item><title>Code Snippetry: C# Asynchronous Actions</title><link>http://blogs.claritycon.com/blogs/peter_miller/archive/2010/02/13/code-snippetry-c-asynchronous-actions.aspx</link><pubDate>Sat, 13 Feb 2010 22:38:46 GMT</pubDate><guid isPermaLink="false">da947a97-509e-40e6-bbb5-1443ad47bf4e:111171</guid><dc:creator>pmiller</dc:creator><slash:comments>1</slash:comments><description>&lt;p&gt;For the time keeping component that I’ve mentioned before, one of the requirements was that it be able to run multiple actions or tasks at a given point in time. In case some of these tasks were particularly long running the idea was to run them in the background, rather than potentially block the main thread and miss a subsequent scheduled time. We also wanted to keep track of a task failing to execute properly and report back on that.&lt;/p&gt;  &lt;p&gt;C# 3.0 provides some elegant and concise ways to do this. My exact implementation was pretty particular to our problem space, but for blogging’s sake, I abstracted out a basic and version of it for your convenience.&lt;/p&gt;  &lt;p&gt;We’ll start from the top with usage:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;    class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Program
    &lt;/span&gt;{
        &lt;span style="color:blue;"&gt;static void &lt;/span&gt;Main(&lt;span style="color:blue;"&gt;string&lt;/span&gt;[] args)
        {
            &lt;span style="color:blue;"&gt;int &lt;/span&gt;i = 0;
            &lt;span style="color:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;Action&lt;/span&gt;&amp;gt; actionsToExecuteAsync = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;Action&lt;/span&gt;&amp;gt;() 
            {
                () =&amp;gt;  System.&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;executed action 1&amp;quot;&lt;/span&gt;),
                () =&amp;gt;  System.&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;executed action 2&amp;quot;&lt;/span&gt;),
                () =&amp;gt;  System.&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;exception time: {0}&amp;quot;&lt;/span&gt;, 1/i),
                () =&amp;gt;  System.&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;executed action 4&amp;quot;&lt;/span&gt;)
            };
            &lt;span style="color:#2b91af;"&gt;AsyncUtil&lt;/span&gt;.ExecuteAsync(actionsToExecuteAsync, HandleException);
            System.&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.ReadLine();
        }

        &lt;span style="color:blue;"&gt;static void &lt;/span&gt;HandleException(&lt;span style="color:#2b91af;"&gt;Exception &lt;/span&gt;e)
        {
            System.&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;exception: {0}&amp;quot;&lt;/span&gt;, e);
        }
    }&lt;/pre&gt;

&lt;p&gt;There is a heavy helping of syntactic sugar here as I create some anonymous delegates (Action’s) to execute and put them in a list using a collection initializer. Next up I call the ExecuteAsync method and wait to see the results. Which look something like this:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;executed action 1 
    &lt;br /&gt;executed action 2 

    &lt;br /&gt;executed action 4 

    &lt;br /&gt;exception: System.DivideByZeroException: Attempted to divide by zero. 

    &lt;br /&gt;&amp;#160;&amp;#160; at AsyncWorker.Program.&amp;lt;&amp;gt;c__DisplayClass8.&amp;lt;Main&amp;gt;b__3() in C:\Users\Peter\src\ 

    &lt;br /&gt;AsyncWorker\AsyncWorker\Program.cs:line 17 

    &lt;br /&gt;&amp;#160;&amp;#160; at AsyncWorker.AsyncUtil.&amp;lt;&amp;gt;c__DisplayClass3.&amp;lt;ExecuteAsync&amp;gt;b__0(Object state) 

    &lt;br /&gt;in C:\Users\Peter\src\AsyncWorker\AsyncWorker\AsyncUtil.cs:line 20&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So we’ve got our tasks executing and an exception in one of them being handled by the HandleException method.&lt;/p&gt;

&lt;p&gt;Looking behind the curtain:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public static class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;AsyncUtil
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;public static void &lt;/span&gt;ExecuteAsync(&lt;span style="color:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;Action&lt;/span&gt;&amp;gt; actions, &lt;span style="color:#2b91af;"&gt;Action&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;Exception&lt;/span&gt;&amp;gt; exceptionHandler)
    {
        &lt;span style="color:blue;"&gt;foreach &lt;/span&gt;(&lt;span style="color:blue;"&gt;var &lt;/span&gt;action &lt;span style="color:blue;"&gt;in &lt;/span&gt;actions)
        {
            &lt;span style="color:blue;"&gt;var &lt;/span&gt;actionToExecute = action;
            &lt;span style="color:#2b91af;"&gt;ThreadPool&lt;/span&gt;.QueueUserWorkItem(state =&amp;gt;
            {
                &lt;span style="color:blue;"&gt;try
                &lt;/span&gt;{
                    actionToExecute();
                }
                &lt;span style="color:blue;"&gt;catch &lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;Exception &lt;/span&gt;e)
                {
                    exceptionHandler(e);
                }
            }, &lt;span style="color:blue;"&gt;null&lt;/span&gt;);
        }
    }
}&lt;/pre&gt;

&lt;p&gt;Almost more whitespace and curly braces in there then code, but that won’t stop us. Again, with some sugary syntax, I’m throwing the action to a background thread through the call to ThreadPool.QueueUserWorkItem. &lt;/p&gt;

&lt;p&gt;A gotcha was that I have to create the actionToExecute variable to ensure that all threads don’t just execute the last action in the list. Why? Because each thread would get a reference to “action” (from the foreach loop) and by the time they executed, “action” would be the final item in actions. Which is probably more confusing to you then it would be if you just took this code and tried it with and without the extra variable.&lt;/p&gt;

&lt;p&gt;So take it for what it’s worth, but I found this snippet of code to be useful and a pleasant reminder of how expressive you can be in C#.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;---Relevant Links---&lt;/p&gt;

&lt;p&gt;If you care to learn anything about threading in .NET, read this whole threading guide by Joseph Albahari:
  &lt;br /&gt;&lt;a href="http://www.albahari.com/threading/"&gt;http://www.albahari.com/threading/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want to see what’s coming in .NET 4.0 that makes this even easier and more powerful:
  &lt;br /&gt;&lt;a href="http://www.codethinked.com/post/2010/01/25/NET-40-and-SystemThreadingTasks.aspx"&gt;http://www.codethinked.com/post/2010/01/25/NET-40-and-SystemThreadingTasks.aspx&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.claritycon.com/aggbug.aspx?PostID=111171" width="1" height="1"&gt;</description><category domain="http://blogs.claritycon.com/blogs/peter_miller/archive/tags/.NET/default.aspx">.NET</category></item><item><title>Json in .NET</title><link>http://blogs.claritycon.com/blogs/kevin_marshall/archive/2010/02/05/json-in-net.aspx</link><pubDate>Fri, 05 Feb 2010 21:22:17 GMT</pubDate><guid isPermaLink="false">da947a97-509e-40e6-bbb5-1443ad47bf4e:108535</guid><dc:creator>kmarshall</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;I use Json all the time, but I feel like it’s super annoying in .NET.&amp;#160; Typically I’d call some web service that returns Json. In .NET it seems like the best thing to is to define a data contract and use the DataContractSerializer:&lt;/p&gt;  &lt;pre class="csharpcode"&gt;[DataContract]
&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Person
{
    [DataMember]
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; FirstName { get; set; }

    [DataMember]
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; LastName { get; set; }
}&lt;/pre&gt;

&lt;p&gt;then to deserialize whatever string of Json I got back.
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, &amp;quot;Courier New&amp;quot;, courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; Person DeserializeToPerson( &lt;span class="kwrd"&gt;string&lt;/span&gt; jsonString )
{
   &lt;span class="kwrd"&gt;using&lt;/span&gt;( MemoryStream ms = &lt;span class="kwrd"&gt;new&lt;/span&gt; MemoryStream( Encoding.Unicode.GetBytes( jsonString ) ) )
   {
      DataContractJsonSerializer serializer =
         &lt;span class="kwrd"&gt;new&lt;/span&gt; DataContractJsonSerializer( &lt;span class="kwrd"&gt;typeof&lt;/span&gt;( Person ) );
      &lt;span class="kwrd"&gt;return&lt;/span&gt; ( Person )serializer.ReadObject( ms );
    }
}&lt;/pre&gt;

&lt;p&gt;Feels like a lot of code and I need to define the data contract beforehand which seems a little unnecessary given the dynamic nature of web services and Json. Things like the the memory stream reader and getting bytes off the string are brutal. Why can’t i just pass a string to the JsonDataContractSerializer? Some things seem way more complicated in .NET than they need to be. (cref: Calling REST services in .NET)&lt;/p&gt;

&lt;p&gt;What I’d like is something closer to Python.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;import simplejson &lt;span class="kwrd"&gt;as&lt;/span&gt; json
person = json.loads(jsonString)
print person.FirstName&lt;/pre&gt;

&lt;p&gt;That is pretty easy. &lt;/p&gt;

&lt;p&gt;With .NET there are some options like:&lt;/p&gt;

&lt;p&gt;System.Json&lt;/p&gt;

&lt;pre class="csharpcode"&gt;var data = JsonObject.Load(dataStream);  
Console.Writeline(data[&lt;span class="str"&gt;&amp;quot;FirstName&amp;quot;&lt;/span&gt;])&lt;/pre&gt;

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, &amp;quot;Courier New&amp;quot;, courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }

&lt;p&gt;This is pretty close to what I want. The problem is having to cast sub items to things like JsonArray and what not. Secondly, System.Json only works in Silverlight so i can’t use in a web project or desktop app.&lt;/p&gt;

&lt;p&gt;Next option is one of the Json libraries like Json.Net. Not that I mind using any 3rd party DLLs, I just think parsing Json is fairly common if you are calling a rest web service and it should be in the framework, maybe I’m the only one that uses json all the time instead of XML but I’d rather use Lotus Notes everyday than parse XML and you know I hates the Lotus Notes.&lt;/p&gt;

&lt;p&gt;This site has an interesting approach: &lt;a href="http://blog.petegoo.com/archive/2009/10/27/using-json.net-to-eval-json-into-a-dynamic-variable-in.aspx"&gt;http://blog.petegoo.com/archive/2009/10/27/using-json.net-to-eval-json-into-a-dynamic-variable-in.aspx&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2 problems for me. I still need to reference Json.Net and there is that ridiculous looking code to convert to Expando object. I just don’t feel comfortable dropping that blob in my code.&lt;/p&gt;

&lt;p&gt;Ideally Json parsing would be something similar but handled in the framework:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;dynamic person = JsonObject.Load(jsonString)
Console.Writeline(person.FirstName)&lt;/pre&gt;

&lt;p&gt;That makes me happy. No pre-defining a contract and something in the framework that can take a string of Json and return back a dynamic object. There is so much stuff in the .NET framework, why can’t there be useful helpers that do common tasks like this.&lt;/p&gt;

&lt;p&gt;I could totally be missing simpler solutions so feel free to chime in if I’m just an idiot and missing something obvious.&lt;/p&gt;

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, &amp;quot;Courier New&amp;quot;, courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;img src="http://blogs.claritycon.com/aggbug.aspx?PostID=108535" width="1" height="1"&gt;</description></item><item><title>Upcoming TechEd and MSDN Events in the Midwest Region</title><link>http://blogs.claritycon.com/blogs/george_durzi/archive/2010/02/05/upcoming-teched-and-msdn-events-in-the-midwest-region.aspx</link><pubDate>Fri, 05 Feb 2010 13:58:00 GMT</pubDate><guid isPermaLink="false">da947a97-509e-40e6-bbb5-1443ad47bf4e:108515</guid><dc:creator>gdurzi</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;I volunteer for INETA as the user group mentor for the Midwest Region (IL, IN, and WI).&amp;nbsp; One of the things I&amp;#39;m planning to do differently this year is to better help spread the word on my blog about events happening in the region, whether they&amp;#39;re Microsoft or user group organized and hosted.&amp;nbsp;&lt;/p&gt;&lt;p&gt;If your user group is hosting an event such as a code camp, send me a short write up and some photos and I&amp;#39;ll make sure it gets published in the INETA newsletter.&amp;nbsp;&lt;/p&gt;&lt;p class="MsoNormal"&gt;Back to business ... Here&amp;#39;s some info about some Azure and Visual Studio 2010 events that are coming up:&lt;/p&gt;&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;b&gt;TechNet Events Present:  Windows Azure, Hyper-V and  Windows 7 Deployment - 8:30am – 12:00pm&lt;/b&gt;&lt;br /&gt;Get the inside track on new tips, tools and technologies for IT pros. Join your TechNet Events team for a look at Windows Azure™ and learn the basics of this new online service computing platform. Next, we’ll explore how to build a great virtual environment with Windows Server® 2008 R2 and Hyper-V™ version 2.0. We’ll wrap this free, half-day of live learning with a tour of easy deployment strategies for Windows® 7.&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;br /&gt;TOPICS INCLUDE:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; •&amp;nbsp;&amp;nbsp;&amp;nbsp; The Next Wave: Windows Azure&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; •&amp;nbsp;&amp;nbsp;&amp;nbsp; Hyper-V: Tools to Build the Ultimate Virtual Test Network&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; •&amp;nbsp;&amp;nbsp;&amp;nbsp; Automating Your Windows 7 Deployment with MDT 2010&lt;br /&gt;&lt;/p&gt;

&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;Date&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;Location&lt;/b&gt;/&lt;b&gt;Registration&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2/10/2010&lt;/td&gt;&lt;td&gt;&lt;a href="http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032438348&amp;amp;Culture=en-US"&gt;Lombard, IL&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3/9/2010&lt;/td&gt;&lt;td&gt;&lt;a href="http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032439006&amp;amp;Culture=en-US"&gt;Waukesha, WI&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3/11/2010&lt;/td&gt;&lt;td&gt;&lt;a href="http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032439007&amp;amp;Culture=en-US"&gt;Indianapolis, IN&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;


&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;b&gt;MSDN Events Presents: Cloud Computing and Azure - 1:00pm – 4:30pm&lt;/b&gt;&lt;br /&gt;Join your local MSDN Events as we take a deep dive into cloud computing and the Windows Azure Platform.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;TOPICS INCLUDE:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; •&amp;nbsp;&amp;nbsp;&amp;nbsp; What is cloud computing?&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; •&amp;nbsp;&amp;nbsp;&amp;nbsp; Running web and web service applications in the cloud&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; •&amp;nbsp;&amp;nbsp;&amp;nbsp; Using the Windows Azure and local developer cloud fabric&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; •&amp;nbsp;&amp;nbsp;&amp;nbsp; Getting started – tools, SDKs and accounts&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; •&amp;nbsp;&amp;nbsp;&amp;nbsp; Writing applications for Windows Azure&lt;br /&gt;&lt;/p&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;Date&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;Location/Registration&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2/10/2010&lt;/td&gt;&lt;td&gt;&lt;a href="http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032438176&amp;amp;Culture=en-US"&gt;Lombard, IL&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;b&gt;MSDN Events Presents: Visual Studio 2010, .NET Framework 4.0 and SharePoint Development&amp;nbsp; - 1:00pm – 4:30pm&lt;/b&gt;&lt;br /&gt;Join your local MSDN Events team for a lively tour our latest version of Visual Studio and the .NET Framework. We’ll start with an overview the IDE and explore how you can use the latest features to develop great applications in a flash. Next, we’ll look at the newest changes to the .NET Framework and how you can leverage them today.&amp;nbsp; Finally, we end the day by looking at the new tools in Visual Studio that will supercharge your SharePoint development.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;TOPICS INCLUDE:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; •&amp;nbsp;&amp;nbsp;&amp;nbsp; What’s new in Visual Studio 2010&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; •&amp;nbsp;&amp;nbsp;&amp;nbsp; What’s new in .NET Framework 4.0&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; •&amp;nbsp;&amp;nbsp;&amp;nbsp; SharePoint Development using Visual Studio 2010&amp;nbsp;&amp;nbsp; &lt;br /&gt;&lt;/p&gt;

&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;Date&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;Location/Registration&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3/9/2010&lt;/td&gt;&lt;td&gt;&lt;a href="http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032439300&amp;amp;Culture=en-US"&gt;Waukesha, WI&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3/11/2010&lt;/td&gt;&lt;td&gt;&lt;a href="http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032439301&amp;amp;Culture=en-US"&gt;Indianapolis, IN&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;

&lt;img src="http://blogs.claritycon.com/aggbug.aspx?PostID=108515" width="1" height="1"&gt;</description></item><item><title>Surface Apps on Windows 7</title><link>http://blogs.claritycon.com/blogs/kevin_marshall/archive/2010/02/04/surface-apps-on-windows-7.aspx</link><pubDate>Thu, 04 Feb 2010 15:10:47 GMT</pubDate><guid isPermaLink="false">da947a97-509e-40e6-bbb5-1443ad47bf4e:108446</guid><dc:creator>kmarshall</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;I feel like an idiot for not realizing this sooner, but if you have the Surface touchpack for Win7, you can reference those Microsoft.Surface.Touchpack dlls in your Surface app, remove the regular Surface references and change the namespaces and voila, your Surface app runs on Win 7. How did I not know this sooner? That seems fairly awesome to me. Surface apps running on the 3m 10-touch capacitive screen are fantastic.&lt;/p&gt;&lt;img src="http://blogs.claritycon.com/aggbug.aspx?PostID=108446" width="1" height="1"&gt;</description></item><item><title>Random Ideas for Mobile Advertising</title><link>http://blogs.claritycon.com/blogs/kevin_marshall/archive/2010/02/04/random-ideas-for-mobile-advertising.aspx</link><pubDate>Thu, 04 Feb 2010 14:24:33 GMT</pubDate><guid isPermaLink="false">da947a97-509e-40e6-bbb5-1443ad47bf4e:108435</guid><dc:creator>kmarshall</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;Here are things I’ve been thinking about lately in regards to mobile advertising.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Mobile advertising seems really underdeveloped. Maybe in part because it’s difficult to tailor ads to various devices and it’s easy to push the standard banner ad inventory or just punt on originality and buy Google ad words. (side note – who actually clicks on google ads? how does this make money for anyone? they seem so worthless) &lt;/li&gt;    &lt;li&gt;Local advertising also seems fairly weak. What replaces local business ads in local papers once they all die out? It doesn’t seem effective for those businesses to buy google ad words. The geographic targeting seems limited and again, who clicks on those ads. There seems to be room for someone to come in and dominate advertising on the local level similar to what google did with online ads in general. Make it super easy and cheap for local businesses to display ads to people that are within a given radius of their business.&lt;/li&gt;    &lt;li&gt;My ideal mobile advertising scenario is close to what Foursquare has done. I check-in at one venue and it alerts me of specials nearby.&amp;#160; Although it’s pretty basic in Foursquare. It seems like it could be way more targeted. I check-in at a bar and it could present offers for drink specials at the bar next door. I love the market that could develop for bidding on what gets displayed when you check-in at certain venues. (Side note – I really want to see sponsored badges on Foursquare seems like a great revenue model. Bonus points if the foursquare app handles mobile payments to track actually getting those badges. Pay for 10 lattes with the foursqaure app, get the latte lover badge)&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Ad words and banner ads just seem lazy. Want to target rich people? put a banner ad on forbes. Want to target people who like to ski? buy an ad word for “ski”&lt;/p&gt;  &lt;p&gt;Here is what I want in ads:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Contextual relevant – This is the whole reason facebook ads are worthless. Just because I like books by Michael Chabon, doesn’t mean I want to see an for his book. I probably already have it and most likely I was just browsing someone’s drunken party pics so I was too distracted to notice the ad anyway.&lt;/li&gt;    &lt;li&gt;Engaging not just distracting – There are a lot of talented agencies out there, do something good. Make me want to experience the ad instead of just clogging up the intertubes and my screen with your 120x240 animated gif.&lt;/li&gt;    &lt;li&gt;Demographically relevant – I like that Hulu let’s me choose. I’d rather watch the Smirnof ad than the trailer for the new Sex &amp;amp; the City movie. (Bonus points to Hulu for recognizing that if you show me a 10 second ad instead of 3 mins, I will actually pay attention because it’s not enough time for me to leave the room)&lt;/li&gt;    &lt;li&gt;Geographically focused – I see ads for Sonic on TV sometimes. I want that slushy and tater tots shown. There is no Sonic in San Francisco. That makes me sad. This shouldn’t happen.&lt;/li&gt;    &lt;li&gt;Value Added – Mint does this well. I don’t mind seeing credit card or bank ads because they are presented in a helpful manner and again are contextually relevant. The same ad for a “no limits platinum joie de vivre” card shown on espn.com just pisses me off and ad block is going to boot it off my screen&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Mobile advertising seems like it could knock all these out. I’m out shopping, I check-in at the Extra Big &amp;amp; Tall show me an ad for a sale on husky fleece pants at Old Navy next door. Maybe include multiple product photos or a little video. You can even scan the ad when i purchase said husky fleece pants to complete the feedback loop. Contextually relevant – I’m shopping, Engaging – some multi-media action, Demographically relevant – I’m a big guy who like comfy pants, Geographically focused – It’s for the store next door and it adds value – I saved some money or you sold me on something I didn’t think I even needed. &lt;/p&gt;  &lt;p&gt;Is this too much to ask for? I submit no. Stop wasting time on this pennies per billion impression non-sense. Advertisers should be able to get much higher ROI on ads and I shouldn’t have to be inundated with crap. Ads are always going to be a reality, let&amp;#39;s just make them not suck so much.&lt;/p&gt;&lt;img src="http://blogs.claritycon.com/aggbug.aspx?PostID=108435" width="1" height="1"&gt;</description></item><item><title>Kindle App Idea #1</title><link>http://blogs.claritycon.com/blogs/kevin_marshall/archive/2010/02/04/kindle-app-idea-1.aspx</link><pubDate>Thu, 04 Feb 2010 13:44:16 GMT</pubDate><guid isPermaLink="false">da947a97-509e-40e6-bbb5-1443ad47bf4e:108433</guid><dc:creator>kmarshall</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;I’m thinking I’ll just start blogging the random ideas I have. Maybe they are good and i will eventually do it or maybe someone else will and I reap the benefits or maybe they suck and nothing happens. Either way, I get a +1 on my blogging stats.&lt;/p&gt;  &lt;p&gt;I love my kindle and I think the demise of e-Ink in favor of&amp;#160; reading on a tablets is overrated. The Kindle app store seemed like an obvious idea. Amazon clearly needs to grow the device and lots of people are unwilling to pay $200+ for a device that “just reads books” Not that there is anything wrong with that. Plus they can charge other people for apps without actually having to think of new uses for the Kindle themselves. Well played Amazon.&lt;/p&gt;  &lt;p&gt;So idea #1. Facebook on the Kindle. Not original right? I don’t want a Facebook client because I rarely use Facebook anymore. The one really useful thing I like about Facebook is Facebook Connect. I really just want my list of friends and their data. I want the Kindle Facebook app to prompt me for a review after I finish a book and post that to Facebook. Then I want to be able to browse books my friends liked and click to buy. I read a fair amount of books and I’m always interested in recommendations. There are bunch of social book sites out there, but I hate having to enter stuff manually. The Kindle knows when I finish a book so I’d like to just take care of it then automagically. Cross posting the review to Amazon would be nice because I value the ratings on there, but I don’t have “friends” on Amazon so there isn’t an easy way to see what they recommend.&lt;/p&gt;  &lt;p&gt;I have no idea what the SDK allows though. It would be great if there was some OnBookCompleted event that you could attach apps to. Also it’s Java and the thought of using Java again makes Kevin the Coder cower in fear. Maybe someone can get JRuby or Jython running on there.&lt;/p&gt;  &lt;p&gt;That or it could just tweet the books I read automatically because you really can’t overshare enough on Twitter.&lt;/p&gt;&lt;img src="http://blogs.claritycon.com/aggbug.aspx?PostID=108433" width="1" height="1"&gt;</description></item><item><title>Experimenting with inter-role communication on Azure for caching</title><link>http://blogs.claritycon.com/blogs/kevin_marshall/archive/2010/02/04/experimenting-with-inter-role-communication-on-azure-for-caching.aspx</link><pubDate>Thu, 04 Feb 2010 12:25:00 GMT</pubDate><guid isPermaLink="false">da947a97-509e-40e6-bbb5-1443ad47bf4e:108430</guid><dc:creator>kmarshall</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;It’s been awhile since I’ve used Azure. The new storage libraries are a welcome addition. As a better diagnostic framework and inter-role communication. In a previous Azure project, I wanted to use ASP.NET caching on the web role, but that breaks down if you start to run multiple instances. With inter-role communication it seems like you could use caching on the server as long as you notify the other instances of updates to the cache. I wrote a little prototype to do that. It’s fairly basic and I haven’t tested it on a real deployment or benchmarked etc. Basically this may just be a terrible way of doing things.&lt;/p&gt;  &lt;p&gt;First I defined a contract for the cache messages:&lt;/p&gt;  &lt;div class="csharpcode"&gt;   &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.ServiceModel;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; MvcWebRole1.Caching&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;    &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;    &lt;span class="rem"&gt;/// Defines the contract for the cache service.&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;    &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;    [ServiceContract]&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;interface&lt;/span&gt; ICacheService&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;        [OperationContract(IsOneWay = &lt;span class="kwrd"&gt;true&lt;/span&gt;)]&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;        &lt;span class="kwrd"&gt;void&lt;/span&gt; Insert(&lt;span class="kwrd"&gt;string&lt;/span&gt; key, &lt;span class="kwrd"&gt;object&lt;/span&gt; &lt;span class="kwrd"&gt;value&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;        [OperationContract(IsOneWay = &lt;span class="kwrd"&gt;true&lt;/span&gt;)]&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;        &lt;span class="kwrd"&gt;void&lt;/span&gt; Remove(&lt;span class="kwrd"&gt;string&lt;/span&gt; key);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;    }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, &amp;quot;Courier New&amp;quot;, courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/p&gt;

&lt;p&gt;Next I implemented the service for that contract. &lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Web;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Diagnostics;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Linq;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.ServiceModel;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Threading;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; Microsoft.WindowsAzure.Diagnostics;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; Microsoft.WindowsAzure.ServiceRuntime;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; MvcWebRole1.Caching&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;&lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;    &lt;span class="rem"&gt;/// Implementation of the WCF cache service.&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;    &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;    [ServiceBehavior(&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;        InstanceContextMode = InstanceContextMode.Single,&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;        ConcurrencyMode = ConcurrencyMode.Multiple,&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;&lt;span class="preproc"&gt;#if&lt;/span&gt; DEBUG&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;        IncludeExceptionDetailInFaults = &lt;span class="kwrd"&gt;true&lt;/span&gt;,&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;&lt;span class="preproc"&gt;#else&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  21:  &lt;/span&gt;        IncludeExceptionDetailInFaults = &lt;span class="kwrd"&gt;false&lt;/span&gt;,&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  22:  &lt;/span&gt;&lt;span class="preproc"&gt;#endif&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  23:  &lt;/span&gt; AddressFilterMode = AddressFilterMode.Any)]&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  24:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; CacheService : ICacheService&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  25:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  26:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Insert(&lt;span class="kwrd"&gt;string&lt;/span&gt; key, &lt;span class="kwrd"&gt;object&lt;/span&gt; &lt;span class="kwrd"&gt;value&lt;/span&gt;)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  27:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  28:  &lt;/span&gt;            HttpRuntime.Cache.Insert(key, &lt;span class="kwrd"&gt;value&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  29:  &lt;/span&gt;            Trace.TraceInformation(String.Format(&lt;span class="str"&gt;&amp;quot;Added: {0} to key: {1} from broadcast&amp;quot;&lt;/span&gt;, &lt;span class="kwrd"&gt;value&lt;/span&gt;, key));&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  30:  &lt;/span&gt;        }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  31:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  32:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Remove(&lt;span class="kwrd"&gt;string&lt;/span&gt; key)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  33:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  34:  &lt;/span&gt;            HttpRuntime.Cache.Remove(key);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  35:  &lt;/span&gt;            Trace.TraceInformation(String.Format(&lt;span class="str"&gt;&amp;quot;Removed key: {0} from broadcast&amp;quot;&lt;/span&gt;, key));&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  36:  &lt;/span&gt;        }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  37:  &lt;/span&gt;    }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  38:  &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, &amp;quot;Courier New&amp;quot;, courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }

&lt;p&gt;That handles the inserts / deletes the cached items when one instance broadcasts a cache update.&lt;/p&gt;

&lt;p&gt;The next bit of code is used to cache on one instance and then broadcast that info out to the other roles.&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Diagnostics;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Linq;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.ServiceModel;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Threading;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Web;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; Microsoft.WindowsAzure.Diagnostics;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; Microsoft.WindowsAzure.ServiceRuntime;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; MvcWebRole1.Caching&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; SynchedCache&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;enum&lt;/span&gt; BroadcastType&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;            Insert,&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;            Remove&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;        }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Insert(&lt;span class="kwrd"&gt;string&lt;/span&gt; key, &lt;span class="kwrd"&gt;object&lt;/span&gt; &lt;span class="kwrd"&gt;value&lt;/span&gt;)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  21:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  22:  &lt;/span&gt;            HttpRuntime.Cache.Insert(key, &lt;span class="kwrd"&gt;value&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  23:  &lt;/span&gt;            Trace.TraceInformation(String.Format(&lt;span class="str"&gt;&amp;quot;Added: {0} to key: {1}&amp;quot;&lt;/span&gt;, &lt;span class="kwrd"&gt;value&lt;/span&gt;, key));&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  24:  &lt;/span&gt;            BroadcastCacheUpdate(BroadcastType.Insert, &lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span class="kwrd"&gt;object&lt;/span&gt;[] {key, &lt;span class="kwrd"&gt;value&lt;/span&gt;});&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  25:  &lt;/span&gt;        }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  26:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  27:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Remove(&lt;span class="kwrd"&gt;string&lt;/span&gt; key)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  28:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  29:  &lt;/span&gt;            HttpRuntime.Cache.Remove(key);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  30:  &lt;/span&gt;            Trace.TraceInformation(String.Format(&lt;span class="str"&gt;&amp;quot;Removed key: {0}&amp;quot;&lt;/span&gt;, key));&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  31:  &lt;/span&gt;            BroadcastCacheUpdate(BroadcastType.Remove, &lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span class="kwrd"&gt;object&lt;/span&gt;[] { key });&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  32:  &lt;/span&gt;        }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  33:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  34:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;object&lt;/span&gt; Get(&lt;span class="kwrd"&gt;string&lt;/span&gt; key)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  35:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  36:  &lt;/span&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; HttpRuntime.Cache.Get(key);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  37:  &lt;/span&gt;        }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  38:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  39:  &lt;/span&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; BroadcastCacheUpdate(BroadcastType type, &lt;span class="kwrd"&gt;params&lt;/span&gt; &lt;span class="kwrd"&gt;object&lt;/span&gt;[] args)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  40:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  41:  &lt;/span&gt;            &lt;span class="rem"&gt;// iterate over all instances of the internal endpoint except the current role - no need to notify itself&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  42:  &lt;/span&gt;            var current = RoleEnvironment.CurrentRoleInstance;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  43:  &lt;/span&gt;            var endPoints = current.Role.Instances.Where(instance =&amp;gt; instance != current)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  44:  &lt;/span&gt;                            .Select(instance =&amp;gt; instance.InstanceEndpoints[&lt;span class="str"&gt;&amp;quot;InternalHttpIn&amp;quot;&lt;/span&gt;]);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  45:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  46:  &lt;/span&gt;            &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var ep &lt;span class="kwrd"&gt;in&lt;/span&gt; endPoints)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  47:  &lt;/span&gt;            {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  48:  &lt;/span&gt;                EndpointAddress address =&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  49:  &lt;/span&gt;                    &lt;span class="kwrd"&gt;new&lt;/span&gt; EndpointAddress(String.Format(&lt;span class="str"&gt;&amp;quot;http://{0}/InternalHttpIn&amp;quot;&lt;/span&gt;, ep.IPEndpoint));&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  50:  &lt;/span&gt;                ICacheService client = WebRole.Factory.CreateChannel(address);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  51:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  52:  &lt;/span&gt;                &lt;span class="kwrd"&gt;try&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  53:  &lt;/span&gt;                {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  54:  &lt;/span&gt;                    &lt;span class="kwrd"&gt;string&lt;/span&gt; key = args[0].ToString();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  55:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  56:  &lt;/span&gt;                    &lt;span class="kwrd"&gt;switch&lt;/span&gt; (type)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  57:  &lt;/span&gt;                    {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  58:  &lt;/span&gt;                        &lt;span class="kwrd"&gt;case&lt;/span&gt; BroadcastType.Insert:&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  59:  &lt;/span&gt;                            client.Insert(key, args[1]);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  60:  &lt;/span&gt;                            &lt;span class="kwrd"&gt;break&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  61:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  62:  &lt;/span&gt;                        &lt;span class="kwrd"&gt;case&lt;/span&gt; BroadcastType.Remove:&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  63:  &lt;/span&gt;                            client.Remove(key);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  64:  &lt;/span&gt;                            &lt;span class="kwrd"&gt;break&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  65:  &lt;/span&gt;                    }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  66:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  67:  &lt;/span&gt;                    ((ICommunicationObject)client).Close();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  68:  &lt;/span&gt;                }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  69:  &lt;/span&gt;                &lt;span class="kwrd"&gt;catch&lt;/span&gt; (TimeoutException timeoutException)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  70:  &lt;/span&gt;                {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  71:  &lt;/span&gt;                    Trace.TraceError(&lt;span class="str"&gt;&amp;quot;Unable to notify web role instance &amp;#39;{0}&amp;#39;. The service operation timed out. {1}&amp;quot;&lt;/span&gt;, &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  72:  &lt;/span&gt;                        ep.RoleInstance.Id, timeoutException.Message);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  73:  &lt;/span&gt;                    ((ICommunicationObject)client).Abort();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  74:  &lt;/span&gt;                }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  75:  &lt;/span&gt;                &lt;span class="kwrd"&gt;catch&lt;/span&gt; (CommunicationException communicationException)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  76:  &lt;/span&gt;                {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  77:  &lt;/span&gt;                    Trace.TraceError(&lt;span class="str"&gt;&amp;quot;Unable to notify web role instance &amp;#39;{0}&amp;#39;. There was a communication problem. {1} - {2}&amp;quot;&lt;/span&gt;, &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  78:  &lt;/span&gt;                        ep.RoleInstance.Id, communicationException.Message, communicationException.StackTrace);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  79:  &lt;/span&gt;                    ((ICommunicationObject)client).Abort();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  80:  &lt;/span&gt;                }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  81:  &lt;/span&gt;            }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  82:  &lt;/span&gt;        }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  83:  &lt;/span&gt;    }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  84:  &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, &amp;quot;Courier New&amp;quot;, courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Finally in your page you can perform operations on the cache like so. &lt;/p&gt;

&lt;pre class="csharpcode"&gt;SynchedCache.Insert(key, DateTime.Now.ToString());.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, &amp;quot;Courier New&amp;quot;, courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/pre&gt;

&lt;p&gt;That call will then notify all the other web roles running. Of course running AppFabric Caching on Azure would be a much better solution once available, but the inter-role communication is still nice to have for other stuff.&lt;/p&gt;&lt;img src="http://blogs.claritycon.com/aggbug.aspx?PostID=108430" width="1" height="1"&gt;</description></item><item><title>High Attention, Low Distraction</title><link>http://blogs.claritycon.com/blogs/peter_miller/archive/2010/02/03/high-attention-low-distraction.aspx</link><pubDate>Thu, 04 Feb 2010 05:17:47 GMT</pubDate><guid isPermaLink="false">da947a97-509e-40e6-bbb5-1443ad47bf4e:108403</guid><dc:creator>pmiller</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;&lt;a href="http://blogs.claritycon.com/blogs/peter_miller/focus_53635E11.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="focus" border="0" alt="focus" src="http://blogs.claritycon.com/blogs/peter_miller/focus_thumb_4E80AA55.png" width="244" height="169" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Truly paying attention can be one of the hardest things to do. Even when you are doing something you want to do, say solving an interesting problem, your mind flits about. In a five minute interval you might answer an IM, check your email, check twitter and oh yeah, think about that problem you are working on.&lt;/p&gt;  &lt;p&gt;There is a lot of literature out there around “flow” and the efficiency of focusing your attention on just one task. If you are working as an engineer or implementer on a project, common ways to help reduce these distractions are to put up a red flag (physically or with a do not disturb online status) or put on your headphones. You can also try to increase your focus by self imposing time boxes on your schedule, a la the Pomodoro Technique of 25 minute bursts of concentrated activity.&lt;/p&gt;  &lt;p&gt;That’s at an individual level. To keep a software team focused, I’ve learned by counter example that the key is for the team to be highly focused on the smallest number of tasks you can get away with. Again, this is not easy to accomplish, but Agile methodologies have a lot to say on this.&lt;/p&gt;  &lt;p&gt;From agile in general, comes the phrase “done done.” Meaning work on a task until the code works, is documented, tested, builds and deploys smoothly. This requires extra discipline on the part of the developer as making the code work is the fun part, whereas the rest just seems like extra effort. This also requires discipline on the part of the team lead to allow this “extra” work to be completed when the developer could go on to make something else work. The benefit is you don’t have to backtrack as much or have a stressful big bang at the end of a cycle to do all your integration, building, testing and documenting.&lt;/p&gt;  &lt;p&gt;“Done done” talks about how to work on a task, which doesn’t help if you are overloaded with too many. Scrum addresses this problem through sprint planning, where tasks are given estimates and only X amount of work is allowed into a sprint. This should result in fewer tasks per developer, but not always. Again, discipline is the key as the scrum master and product owner have to engage in a give and take to keep scope manageable. If the product owner says you have to do everything this sprint, no matter what, you aren’t doing agile anymore, you’re just fire fighting.&lt;/p&gt;  &lt;p&gt;Kanban or lean methodologies, deriving from production environments, focus on limiting the number of tasks going on at once. Every task goes through distinct stages and a new task cannot be added until another task exits the last stage. Progress is tracked visually on a kanban board. So there are not really sprints, so much as a continuous low flow of focused activity. I haven’t done kanban myself, but like scrum, it implies a give and take between the team and the other stakeholders to understand that doing less at once, does mean doing less for the project lifecycle.&lt;/p&gt;  &lt;p&gt;So while Agile is becoming mainstream, and the concept of flow is almost passé at this point, I don’t get the sense that it is mainstream to follow through on their convergence of focusing more on fewer items at a time. This seems to be a general trend, where we all like the idea of being Agile, but think a light process = a free and easy process. After a rather unsuccessful attempt at Scrum with that concept in my mind, I can assure you it is not the case. Good process is difficult, but when did difficulty ever stop us before?&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;--Relevant Links--&lt;/p&gt;  &lt;p&gt;The Pomodoro Technique and tomato timers:    &lt;br /&gt;&lt;a href="http://www.pomodorotechnique.com/"&gt;http://www.pomodorotechnique.com/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;If you like “Done done”, check out:    &lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Buffalo_buffalo_Buffalo_buffalo_buffalo_buffalo_Buffalo_buffalo"&gt;http://en.wikipedia.org/wiki/Buffalo_buffalo_Buffalo_buffalo_buffalo_buffalo_Buffalo_buffalo&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;More on “done done”:    &lt;br /&gt;&lt;a href="http://blog.phpdeveloper.org/?p=148"&gt;http://blog.phpdeveloper.org/?p=148&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;InfoQ’s stuff is pretty good, haven’t read this yet myself, but looks promising:    &lt;br /&gt;&lt;a href="http://www.infoq.com/minibooks/kanban-scrum-minibook"&gt;http://www.infoq.com/minibooks/kanban-scrum-minibook&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Agile is now mainstream:    &lt;br /&gt;&lt;a href="http://www.computerworld.in/articles/agile-software-development-now-mainstream"&gt;http://www.computerworld.in/articles/agile-software-development-now-mainstream&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.claritycon.com/aggbug.aspx?PostID=108403" width="1" height="1"&gt;</description></item><item><title>Stumbling Through – Clearing Test K2 Data</title><link>http://blogs.claritycon.com/blogs/tim_byrne/archive/2010/01/27/stumbling-through-clearing-test-k2-data.aspx</link><pubDate>Wed, 27 Jan 2010 18:38:54 GMT</pubDate><guid isPermaLink="false">da947a97-509e-40e6-bbb5-1443ad47bf4e:106998</guid><dc:creator>tbyrne</dc:creator><slash:comments>1</slash:comments><description>&lt;p&gt;In many K2 projects I&amp;#39;ve worked on, we end up having to tie existing business data into the various workflow processes.&amp;#160; While k2 provides a means to do this via process/activity data fields, they tend to be difficult to query against and can be inefficient compared to an existing schema that has been optimized specifically for the business data involved.&amp;#160; That, and why store the same data twice if it already exists in a database?&amp;#160; That discussion is not the point of this blog entry, though it is an interesting topic that I may revisit later. For now, lets roll with the assumption that we have data in a custom database that is related to K2 process instances.&amp;#160; &lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;During development and testing cycles, one of the tedious activities for me has been trying to clean up old test data, particularly when there are thousands of process instances involved.&amp;#160; The reason for this is because cleaning data in the scenario described above is a two-step process:&amp;#160; First delete the custom database data and then delete the K2 process instances.&amp;#160; Deleting the custom database data is no problem - write a quick SQL script and run it as needed but cleaning the K2 process instances is a different story... &lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;There are two main ways to clear K2 process instances:&amp;#160; via API or via Workspace.&amp;#160; While we could write a program that would execute our database clean up scripts and then iterate through and delete our K2 process instances via API, but that is too much work for this &lt;strike&gt;lazy&lt;/strike&gt; busy developer.&amp;#160; The workspace approach can be a real hassle when there are thousands of process instances because let&amp;#39;s face it - deleting more than 100 process instances at a time is not a snappy experience through today&amp;#39;s workspace.&amp;#160; &lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;After wrestling with clearing test data repeatedly through the workspace, I finally posed myself the question:&amp;#160; Why is it that we can&amp;#39;t we delete process instances through the same SQL script we use to clear the custom data?&amp;#160; Surely, the workspace uses some sort of stored procedure(s) when it deletes a process instance, right?&amp;#160; I started digging around through the K2 databases to see if any stored procedures jumped out at me as obvious choices and while there were a few likely candidates, none of them fit the bill.&amp;#160; Frustrated, I posed the question on the &lt;a href="http://www.k2underground.com/forums/t/11951.aspx"&gt;K2Underground&lt;/a&gt; and was quickly directed to an &lt;a href="http://www.k2underground.com/blogs/johnny/archive/2008/04/15/deleting-obsolete-process-instances-from-a-k2-net-2003-or-k2-blackpearl-database.aspx"&gt;article that came close to what I was trying to accomplish&lt;/a&gt;.&amp;#160; Using the code in this article as a base, I tweaked it until it was capable of clearing all process instances for a given folder (could easily work for a given process name as well) and it has been so useful to me that I figured I&amp;#39;d share it here.&amp;#160; Be warned, this is slapped together for development assistance, and should by no means be used on a production box!&amp;#160; Happy data clearing... &lt;/p&gt;  &lt;p&gt;/*   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Delete all workflow process instances    &lt;br /&gt;*/    &lt;br /&gt;Use K2Server    &lt;br /&gt;DECLARE @FOLDERNAME VARCHAR(100)    &lt;br /&gt;SET @FOLDERNAME = &amp;#39;[Enter Folder Name Here]&amp;#39; &lt;/p&gt;  &lt;p&gt;PRINT &amp;#39;Starting to remove Process Instances for &amp;#39; + @FOLDERNAME &lt;/p&gt;  &lt;p&gt;PRINT &amp;#39;Getting List of Process Instances&amp;#39;   &lt;br /&gt;SELECT ID INTO #TMP FROM _ProcInst    &lt;br /&gt;WHERE PROCID IN    &lt;br /&gt;(    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; SELECT ID    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; FROM _PROC    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; WHERE PROCSETID IN    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; (    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; SELECT ID    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; FROM _PROCSET    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; WHERE FOLDER =&amp;#160; @FOLDERNAME    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; )    &lt;br /&gt;) &lt;/p&gt;  &lt;p&gt;PRINT &amp;#39;Removing Process Instances from _IPC&amp;#39;   &lt;br /&gt;DELETE _IPC    &lt;br /&gt;FROM _IPC    &lt;br /&gt;INNER JOIN #TMP    &lt;br /&gt;ON SrcProcInstID = #TMP.ID    &lt;br /&gt;PRINT CAST(@@ROWCOUNT AS VARCHAR(10)) + &amp;#39; records removed from _IPC&amp;#39; &lt;/p&gt;  &lt;p&gt;PRINT &amp;#39;Removing Process Instances from _ProcInst&amp;#39;   &lt;br /&gt;DELETE _ProcInst    &lt;br /&gt;FROM _ProcInst    &lt;br /&gt;INNER JOIN #TMP    &lt;br /&gt;ON _ProcInst.ID = #TMP.ID    &lt;br /&gt;PRINT CAST(@@ROWCOUNT AS VARCHAR(10)) + &amp;#39; records removed from _ProcInst&amp;#39; &lt;/p&gt;  &lt;p&gt;PRINT &amp;#39;Completed removing completed process instances from K2ServerLog for folder &amp;#39; + @FOLDERNAME &lt;/p&gt;  &lt;p&gt;DROP TABLE #TMP &lt;/p&gt;  &lt;p&gt;Use K2ServerLog &lt;/p&gt;  &lt;p&gt;PRINT &amp;#39;Starting to remove Process Instances for &amp;#39; + @FOLDERNAME &lt;/p&gt;  &lt;p&gt;PRINT &amp;#39;Getting List of Process Instances&amp;#39;   &lt;br /&gt;SELECT ID INTO #TMP2 FROM _ProcInst    &lt;br /&gt;WHERE PROCID IN    &lt;br /&gt;(    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; SELECT ID    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; FROM _PROC    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; WHERE PROCSETID IN    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; (    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; SELECT ID    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; FROM _PROCSET    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; WHERE FOLDER =&amp;#160; @FOLDERNAME    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; )    &lt;br /&gt;) &lt;/p&gt;  &lt;p&gt;PRINT &amp;#39;Removing Process Instances from _ActInst&amp;#39;   &lt;br /&gt;DELETE _ActInst    &lt;br /&gt;FROM _ActInst INNER JOIN #TMP2    &lt;br /&gt;ON ProcInstID = #TMP2.ID    &lt;br /&gt;PRINT CAST(@@ROWCOUNT AS VARCHAR(10)) + &amp;#39; records removed from _ActInst&amp;#39; &lt;/p&gt;  &lt;p&gt;PRINT &amp;#39;Removing Process Instances from _ActInstAudit&amp;#39;   &lt;br /&gt;DELETE _ActInstAudit    &lt;br /&gt;FROM _ActInstAudit    &lt;br /&gt;INNER JOIN #TMP2    &lt;br /&gt;ON ProcInstID = #TMP2.ID    &lt;br /&gt;PRINT CAST(@@ROWCOUNT AS VARCHAR(10)) + &amp;#39; records removed from _ActInstAudit&amp;#39; &lt;/p&gt;  &lt;p&gt;PRINT &amp;#39;Removing Process Instances from _ActInstDest&amp;#39;   &lt;br /&gt;DELETE _ActInstDest    &lt;br /&gt;FROM _ActInstDest    &lt;br /&gt;INNER JOIN #TMP2    &lt;br /&gt;ON ProcInstID = #TMP2.ID    &lt;br /&gt;PRINT CAST(@@ROWCOUNT AS VARCHAR(10)) + &amp;#39; records removed from _ActInstDest&amp;#39; &lt;/p&gt;  &lt;p&gt;PRINT &amp;#39;Removing Process Instances from _ActInstDestData&amp;#39;   &lt;br /&gt;DELETE _ActInstDestData    &lt;br /&gt;FROM _ActInstDestData    &lt;br /&gt;INNER JOIN #TMP2    &lt;br /&gt;ON ProcInstID = #TMP2.ID    &lt;br /&gt;PRINT CAST(@@ROWCOUNT AS VARCHAR(10)) + &amp;#39; records removed from _ActInstDestData&amp;#39; &lt;/p&gt;  &lt;p&gt;PRINT &amp;#39;Removing Process Instances from _ActInstDestDataAudit&amp;#39;   &lt;br /&gt;DELETE _ActInstDestDataAudit    &lt;br /&gt;FROM _ActInstDestDataAudit    &lt;br /&gt;INNER JOIN #TMP2    &lt;br /&gt;ON ProcInstID = #TMP2.ID    &lt;br /&gt;PRINT CAST(@@ROWCOUNT AS VARCHAR(10)) + &amp;#39; records removed from _ActInstDestDataAudit&amp;#39; &lt;/p&gt;  &lt;p&gt;PRINT &amp;#39;Removing Process Instances from _ActInstDestXml&amp;#39;   &lt;br /&gt;DELETE _ActInstDestXml    &lt;br /&gt;FROM _ActInstDestXml    &lt;br /&gt;INNER JOIN #TMP2    &lt;br /&gt;ON ProcInstID = #TMP2.ID    &lt;br /&gt;PRINT CAST(@@ROWCOUNT AS VARCHAR(10)) + &amp;#39; records removed from _ActInstDestXml&amp;#39; &lt;/p&gt;  &lt;p&gt;PRINT &amp;#39;Removing Process Instances from _ActInstDestXmlAudit&amp;#39;   &lt;br /&gt;DELETE _ActInstDestXmlAudit    &lt;br /&gt;FROM _ActInstDestXmlAudit    &lt;br /&gt;INNER JOIN #TMP2    &lt;br /&gt;ON ProcInstID = #TMP2.ID    &lt;br /&gt;PRINT CAST(@@ROWCOUNT AS VARCHAR(10)) + &amp;#39; records removed from _ActInstDestXmlAudit&amp;#39; &lt;/p&gt;  &lt;p&gt;PRINT &amp;#39;Removing Process Instances from _EscInst&amp;#39;   &lt;br /&gt;DELETE _EscInst    &lt;br /&gt;FROM _EscInst    &lt;br /&gt;INNER JOIN #TMP2    &lt;br /&gt;ON ProcInstID = #TMP2.ID    &lt;br /&gt;PRINT CAST(@@ROWCOUNT AS VARCHAR(10)) + &amp;#39; records removed from _EscInst&amp;#39; &lt;/p&gt;  &lt;p&gt;PRINT &amp;#39;Removing Process Instances from _EventInst&amp;#39;   &lt;br /&gt;DELETE _EventInst    &lt;br /&gt;FROM _EventInst    &lt;br /&gt;INNER JOIN #TMP2    &lt;br /&gt;ON ProcInstID = #TMP2.ID    &lt;br /&gt;PRINT CAST(@@ROWCOUNT AS VARCHAR(10)) + &amp;#39; records removed from _EventInst&amp;#39; &lt;/p&gt;  &lt;p&gt;PRINT &amp;#39;Removing Process Instances from _IPC&amp;#39;   &lt;br /&gt;DELETE _IPC    &lt;br /&gt;FROM _IPC    &lt;br /&gt;INNER JOIN #TMP2    &lt;br /&gt;ON SrcProcInstID = #TMP2.ID    &lt;br /&gt;PRINT CAST(@@ROWCOUNT AS VARCHAR(10)) + &amp;#39; records removed from _IPC&amp;#39; &lt;/p&gt;  &lt;p&gt;PRINT &amp;#39;Removing Process Instances from _LogBatch&amp;#39;   &lt;br /&gt;DELETE _LogBatch    &lt;br /&gt;FROM _LogBatch    &lt;br /&gt;INNER JOIN #TMP2    &lt;br /&gt;ON ProcInstID = #TMP2.ID    &lt;br /&gt;PRINT CAST(@@ROWCOUNT AS VARCHAR(10)) + &amp;#39; records removed from _LogBatch&amp;#39; &lt;/p&gt;  &lt;p&gt;PRINT &amp;#39;Removing Process Instances from _LineInst&amp;#39;   &lt;br /&gt;DELETE _LineInst    &lt;br /&gt;FROM _LineInst    &lt;br /&gt;INNER JOIN #TMP2    &lt;br /&gt;ON ProcInstID = #TMP2.ID    &lt;br /&gt;PRINT CAST(@@ROWCOUNT AS VARCHAR(10)) + &amp;#39; records removed from _LineInst&amp;#39; &lt;/p&gt;  &lt;p&gt;PRINT &amp;#39;Removing Process Instances from _ProcInst&amp;#39;   &lt;br /&gt;DELETE _ProcInst    &lt;br /&gt;FROM _ProcInst    &lt;br /&gt;INNER JOIN #TMP2    &lt;br /&gt;ON _ProcInst.ID = #TMP2.ID    &lt;br /&gt;PRINT CAST(@@ROWCOUNT AS VARCHAR(10)) + &amp;#39; records removed from _ProcInst&amp;#39; &lt;/p&gt;  &lt;p&gt;PRINT &amp;#39;Removing Process Instances from _ProcInstAudit&amp;#39;   &lt;br /&gt;DELETE _ProcInstAudit    &lt;br /&gt;FROM _ProcInstAudit    &lt;br /&gt;INNER JOIN #TMP2    &lt;br /&gt;ON ProcInstID = #TMP2.ID    &lt;br /&gt;PRINT CAST(@@ROWCOUNT AS VARCHAR(10)) + &amp;#39; records removed from _ProcInstAudit&amp;#39; &lt;/p&gt;  &lt;p&gt;PRINT &amp;#39;Removing Process Instances from _ProcInstData&amp;#39;   &lt;br /&gt;DELETE _ProcInstData    &lt;br /&gt;FROM _ProcInstData    &lt;br /&gt;INNER JOIN #TMP2    &lt;br /&gt;ON ProcInstID = #TMP2.ID    &lt;br /&gt;PRINT CAST(@@ROWCOUNT AS VARCHAR(10)) + &amp;#39; records removed from _ProcInstData&amp;#39; &lt;/p&gt;  &lt;p&gt;PRINT &amp;#39;Removing Process Instances from _ProcInstDataAudit&amp;#39;   &lt;br /&gt;DELETE _ProcInstDataAudit    &lt;br /&gt;FROM _ProcInstDataAudit    &lt;br /&gt;INNER JOIN #TMP2    &lt;br /&gt;ON ProcInstID = #TMP2.ID    &lt;br /&gt;PRINT CAST(@@ROWCOUNT AS VARCHAR(10)) + &amp;#39; records removed from _ProcInstDataAudit&amp;#39; &lt;/p&gt;  &lt;p&gt;PRINT &amp;#39;Removing Process Instances from _ProcInstXml&amp;#39;   &lt;br /&gt;DELETE _ProcInstXml    &lt;br /&gt;FROM _ProcInstXml    &lt;br /&gt;INNER JOIN #TMP2    &lt;br /&gt;ON ProcInstID = #TMP2.ID    &lt;br /&gt;PRINT CAST(@@ROWCOUNT AS VARCHAR(10)) + &amp;#39; records removed from _ActInst&amp;#39; &lt;/p&gt;  &lt;p&gt;PRINT &amp;#39;Removing Process Instances from _ProcInstXmlAudit&amp;#39;   &lt;br /&gt;DELETE _ProcInstXmlAudit    &lt;br /&gt;FROM _ProcInstXmlAudit    &lt;br /&gt;INNER JOIN #TMP2    &lt;br /&gt;ON ProcInstID = #TMP2.ID    &lt;br /&gt;PRINT CAST(@@ROWCOUNT AS VARCHAR(10)) + &amp;#39; records removed from _ProcInstXmlAudit&amp;#39; &lt;/p&gt;  &lt;p&gt;PRINT &amp;#39;Completed removing completed process instances from K2ServerLog for folder &amp;#39; + @FOLDERNAME &lt;/p&gt;  &lt;p&gt;DROP TABLE #TMP2&lt;/p&gt;&lt;img src="http://blogs.claritycon.com/aggbug.aspx?PostID=106998" width="1" height="1"&gt;</description></item><item><title>More About Time: Leveraging Castle Windsor</title><link>http://blogs.claritycon.com/blogs/peter_miller/archive/2010/01/20/more-about-time-leveraging-castle-windsor.aspx</link><pubDate>Wed, 20 Jan 2010 14:00:00 GMT</pubDate><guid isPermaLink="false">da947a97-509e-40e6-bbb5-1443ad47bf4e:102589</guid><dc:creator>pmiller</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;In a previous post, I mentioned working on a time keeping component. We used this component as the basis of a task scheduling application. Our tasks were represented by classes that implemented a common task interface:&lt;/p&gt;  &lt;pre&gt; 
public interface ICustomTask
{
   CustomTaskResult Execute();
   DateTime? ExecutionTime { get; }
   TimeZoneInfo ExecutionTimeZone { get; }
   string Description { get; }
}

public class CustomTaskResult
{
    public bool WasSuccess { get; set; }
    public string Message { get; set; }
}&lt;/pre&gt;

&lt;p&gt;So far, so good. Next challenge was how do we specify which of these tasks to run, and when? My initial thought was to put these details in an app.config or custom XML file. Task elements with the class name and time as attributes for example. Then additional elements for custom parameters that a task might need to initialize.&lt;/p&gt;

&lt;p&gt;Fortunately enough, I work with some smart people, one of whom gently suggested that rather then create and manage my own custom config file, I instead leverage Castle Windsor (our dependency injection framework) and its configuration.&lt;/p&gt;

&lt;p&gt;I’ll let the code do the talking; here’s a windsor section of an app.config for our task scheduler which will run two tasks at 9pm and the end of every day (the default if no time is specified) respectively:&lt;/p&gt;

&lt;pre&gt;&amp;lt;castle&amp;gt;
   &amp;lt;components&amp;gt;
       &amp;lt;component id=&amp;quot;NightlyProcessing&amp;quot; lifestyle=&amp;quot;transient&amp;quot; 
         service=&amp;quot;Clarity.ICustomTask, Clarity.Task&amp;quot; 
         type=&amp;quot;Clarity.Processing.NightlyTask, Clarity.Processing&amp;quot;&amp;gt;
		&amp;lt;parameters&amp;gt;
		     &amp;lt;timeZone&amp;gt;Eastern Standard Time&amp;lt;/timeZone&amp;gt;
	              &amp;lt;processingTime&amp;gt;9:00 PM&amp;lt;/processingTime&amp;gt;
		  &amp;lt;/parameters&amp;gt;
       &amp;lt;component id=&amp;quot;RunSSISPackage&amp;quot; lifestyle=&amp;quot;transient&amp;quot; 
	service=&amp;quot;Clarity.ICustomTask, Clarity.Task&amp;quot; 
	type=&amp;quot;Clarity.SSIS.PackageTask, Clarity.SSIS&amp;quot;&amp;gt;
       &amp;lt;parameters&amp;gt;
         &amp;lt;description&amp;gt;Nightly Data Archiving&amp;lt;/description&amp;gt;
          &amp;lt;pathToPackage&amp;gt;c:\Data_Archive.dtsx&amp;lt;/PathToPackage&amp;gt;
          &amp;lt;pathToConfigFile&amp;gt;C:\DEV.dtsConfig&amp;lt;/PathToConfigFile&amp;gt;
        &amp;lt;/parameters&amp;gt;
      &amp;lt;/component&amp;gt;
   &amp;lt;/components&amp;gt;
&amp;lt;/castle&amp;gt;&lt;/pre&gt;

&lt;p&gt;The namespaces have been sanitized, but the point is that you can specify parameter elements that map to constructor arguments. So for example, the NightlyTask class has a constructor with a timeZone and processingTime argument that get mapped to the ExecutionTime and ExecutionTimeZone properties on the custom task.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;--- Relevant Links&amp;#160; ---&lt;/p&gt;

&lt;p&gt;To take this to the next level (or if you just don’t like the angle bracket tax):&lt;/p&gt;

&lt;p&gt;&lt;a href="http://sheitm.blogspot.com/2009/05/fluent-castle-windsor-and-configured.html"&gt;http://sheitm.blogspot.com/2009/05/fluent-castle-windsor-and-configured.html&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.claritycon.com/aggbug.aspx?PostID=102589" width="1" height="1"&gt;</description><category domain="http://blogs.claritycon.com/blogs/peter_miller/archive/tags/smiles/default.aspx">smiles</category></item><item><title>Utilizing Custom Fonts with SQL Reporting Services (SSRS) and Exporting to PDF</title><link>http://blogs.claritycon.com/blogs/andrew_karcher/archive/2010/01/18/utilizing-custom-fonts-with-sql-reporting-services-ssrs-and-exporting-to-pdf.aspx</link><pubDate>Mon, 18 Jan 2010 08:41:08 GMT</pubDate><guid isPermaLink="false">da947a97-509e-40e6-bbb5-1443ad47bf4e:103189</guid><dc:creator>akarcher</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;I recently had a unique challenge with SSRS which was the utilization of a Custom Font on an SSRS Report. Normally, I do not think about fonts other than what get installed as system fonts in Windows so this was a fairly new experience. I know a few people who REALLY enjoy fonts in the Design Practice at Clarity, but had never considered the impact and usefulness they can play in SSRS.&amp;#160; It was somewhat difficult to find information about this so I figured I would summarize to save some other people some trouble.&lt;/p&gt;  &lt;p&gt;The report that I had to develop was going to be a customer facing report so there were some fairly exact standards that it needed to comply with both from an aesthetic and regulatory perspective, much more so than most SSRS reports which are generally for internal consumption only. As an idea of some of the requirements take a look at a statement from your cell phone provider, local utility or television provider, and that is similar to what I had to build. If you have never looked very closely at something like that you probably have missed the sheer amount of different fonts, font sizes, font weights, font decorations, and so on that is used in building that statement. Some of the formatting is done based on aesthetics and some is also based on regulations, such as minimum font sizes for those disclaimers that you can barely read on the statement. &lt;/p&gt;  &lt;p&gt;So before I get into the nuts and bolts of this, I need to give a shout out to Andre Milbradt from the SSRS team who was very helpful in clearing up some of the confusion out there for me on font embedding and the PDF Renderer.&lt;/p&gt;  &lt;p&gt;Before we get into SSRS, let’s go into a bit about the different types of fonts out there (Reminder: I am not a Font guy). There are two major types of Fonts out there: True Type (wiki: &lt;a href="http://en.wikipedia.org/wiki/True_Type_Font"&gt;http://en.wikipedia.org/wiki/True_Type_Font&lt;/a&gt; ) and Open Type (wiki: &lt;a href="http://en.wikipedia.org/wiki/OpenType"&gt;http://en.wikipedia.org/wiki/OpenType&lt;/a&gt;). Of these two, SSRS fully supports True Type Fonts and has limited support for Open Type Fonts. Essentially, any Font that can be instantiated by the .Net System.Drawing.Font (http://msdn.microsoft.com/en-us/library/system.drawing.font.aspx) class is supported by SSRS. Because the custom font that we needed was available as both a True Type Font and an Open Type Font, we went with the True Type font since we knew that it would be fully supported.&lt;/p&gt;  &lt;p&gt;So we went ahead and installed the fonts on the developer machine and the SSRS server. On the development machine, you do have to restart Visual Studio after you install the fonts for Visual Studio to pick up on the font. On the server, we were having issues with SSRS picking up the newly installed Font until we restarted the Reporting Services Server. We probably could have just restarted SSRS, but we ended up just restarting the server. If you have never installed a font before (I hadn’t before this project) you can get to the installed fonts by going to Control Panel -&amp;gt; Fonts. For Windows XP and above you can just copy and paste the font files into this directory. For Vista and above, one of the right-click options on the .ttf font file is “Install”.&lt;/p&gt;  &lt;p&gt;I first started developing the report in SSRS 2005, using my custom font and it all looks good. Then I try to export to PDF for the first time and “Uh-Oh”. That doesn’t quite work. And after a bit of research and some verification from the PG team, SSRS 2005 does have limited support PDF Font Embedding, but it is limited to Unicode Data. You can check out the Books Online here (&lt;a href="http://technet.microsoft.com/en-us/library/ms159713(SQL.90).aspx" target="_blank"&gt;http://technet.microsoft.com/en-us/library/ms159713(SQL.90).aspx&lt;/a&gt;) about the behavior in SSRS 2005. You can also check out this post from Robert Bruckner (&lt;a href="http://blogs.msdn.com/robertbruckner/archive/2008/10/27/unicode-in-pdf-font-embedding.aspx" target="_blank"&gt;http://blogs.msdn.com/robertbruckner/archive/2008/10/27/unicode-in-pdf-font-embedding.aspx&lt;/a&gt; ) on the feature in SSRS 2008 CU1, which is the same feature that was also added SSRS 2005 in SP3. So since I was using ANSI text data, it was on to SSRS 2008.&lt;/p&gt;  &lt;p&gt;So I started looking at Books Online for SSRS 2008 and noticed the same restrictions on Font Embedding in PDF as there are in SSRS 2005. If you take a look at the same topic for SSRS 2008 (&lt;a href="http://technet.microsoft.com/en-us/library/ms159713(SQL.100).aspx" target="_blank"&gt;http://technet.microsoft.com/en-us/library/ms159713(SQL.100).aspx&lt;/a&gt;) in the Font Embedding section it still lists the following as a restriction, “The characters in the string that has the Font property set are Unicode, not ANSI. No font embedding occurs for ANSI characters.” After confirmation from the product group, this is incorrect and a User Education bug was submitted to have this documentation fixed. So with that out of the way and we had confirmation that SSRS 2008 will embed fonts within a generated PDF, we developed our report.&lt;/p&gt;  &lt;p&gt;At this point I want to remind you to restart the server after installing your font, because I forgot my own rule to restart the server after installing fonts and was pulling my hair out at one point.&lt;/p&gt;  &lt;p&gt;So after you have developed and deployed your report, you export to PDF and want to verify that your Font got embedded. There are a number of ways to do this. First, check the properties of the PDF. In Acrobat Reader, go to File-&amp;gt;Properties and then click on the Font tab. There should be a listing of Fonts there which should include your custom font. Second, send the PDF to someone who does not have the Font installed. They should see the new custom font as well in their PDF. Lastly, if your custom font is not obvious, having a nice trained designer eye is the best tool you can have to verify the font for you.&lt;/p&gt;  &lt;p&gt;So hopefully this post clears up some confusion on custom fonts and Font Embedding with the PDF Font Renderer.&lt;/p&gt;&lt;img src="http://blogs.claritycon.com/aggbug.aspx?PostID=103189" width="1" height="1"&gt;</description><category domain="http://blogs.claritycon.com/blogs/andrew_karcher/archive/tags/Microsoft+SQL+Server/default.aspx">Microsoft SQL Server</category><category domain="http://blogs.claritycon.com/blogs/andrew_karcher/archive/tags/SQL+Server+2008/default.aspx">SQL Server 2008</category><category domain="http://blogs.claritycon.com/blogs/andrew_karcher/archive/tags/Business+Intelligence/default.aspx">Business Intelligence</category></item><item><title>Agile in Action – TDD Lessons Learned</title><link>http://blogs.claritycon.com/blogs/peter_miller/archive/2010/01/16/agile-in-action-tdd-lessons-learned.aspx</link><pubDate>Sat, 16 Jan 2010 15:46:39 GMT</pubDate><guid isPermaLink="false">da947a97-509e-40e6-bbb5-1443ad47bf4e:102564</guid><dc:creator>pmiller</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;As I continue to explore agile techniques at work, I had the opportunity to do some Test Driven Development, specifically Test First Development. The problem at hand was that our system is composed of several applications, all of which have various actions they have to take every hour or every day at a specific time. As the applications were developed, each application grew out its own time keeping infrastructure.&lt;/p&gt;  &lt;p&gt;If you haven’t had the pleasure yet, working with time, dates and durations in .NET is not as easy as you’d like. It has gotten a lot better since framework 1.0, but it is still a great place for bugs to hatch. And not surprisingly, while each application was able to implement a system that worked &lt;em&gt;most&lt;/em&gt; of the time, the code base was sprawling and behavior was unpredictable.&lt;/p&gt;  &lt;p&gt;With the hindsight that comes after pushing a system to production, my team became convinced that we needed more then working most of the time, we wanted to prove that it worked all the time. Also, having abused the coding principle of (D)on’t (R)epeat (Y)ourself with multiple competing implementations we wanted to settle on one common implementation.&lt;/p&gt;  &lt;p&gt;The approach we took was to throw out the old code, and first define an interface for our time keeper. Now it looks something like this:&lt;/p&gt;  &lt;pre class="code"&gt; public interface ITimekeeper
 {
        event EventHandler HourChanged;
        event EventHandler DayChanged;

        void Initialize(TimeZoneInfo timeZone, DateTime dayChangeTime);
        void RegisterCustomEvent(DateTime time, TimeZoneInfo timeZone, 
					CustomEventCallback callback, object state);
        void Start();
        void Stop();
	...

	IClock Clock { get; set; }
}&lt;/pre&gt;

&lt;p&gt;Now is an important qualifier. We didn’t start out with the right interface, we took an educated guess and then started writing some tests. Importantly, and somewhat surprisingly to me, we got a lot of value out of just trying to write the tests themselves. It was a feedback loop as we’d try to write a test, find the interface clunky, refine the interface , write the test again and then move on. &lt;/p&gt;

&lt;p&gt;We deliberately ignored the implementation at first and defined a reasonably wide set of tests that covered the basic functionality of our component. Then we subjected the interface to its sharpest critique by handing these tests off to another developer on the team and having him implement the code to make them pass.&lt;/p&gt;

&lt;p&gt;In short, TDD drove our component level design to be more elegant, provided a natural way to break out tasks amongst the team, and of course provided us some confidence that the implementation would work. &lt;/p&gt;

&lt;p&gt;I think I am taking a break from the bold prediction business, but this experience definitely has lead me to reconsider some of the points made over a year ago in this post of questionable origin:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.claritycon.com/blogs/peter_miller/archive/2008/10/06/why-test-driven-development-is-a-hard-sell.aspx"&gt;http://blogs.claritycon.com/blogs/peter_miller/archive/2008/10/06/why-test-driven-development-is-a-hard-sell.aspx&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;img src="http://employees.claritycon.com/pmiller/blog/pmiller-headshot.jpg" width="66" height="75" alt="" /&gt;&amp;#160; &lt;em&gt;&amp;lt;--- A questionable dude…&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;--- Related Links ---&lt;/p&gt;

&lt;p&gt;Hat tip to Philipp Sumi, who implemented a nice scheduling library of his own (which I found after I finished my efforts) and provided me some good feedback and insight on TDD.&lt;/p&gt;

&lt;p&gt;&lt;a title="http://www.hardcodet.net/2010/01/lightweight-task-slash-job-scheduling-with-silverlight-support" href="http://www.hardcodet.net/2010/01/lightweight-task-slash-job-scheduling-with-silverlight-support"&gt;http://www.hardcodet.net/2010/01/lightweight-task-slash-job-scheduling-with-silverlight-support&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also, for the eagle eyed amongst you, yes we do have an interface for the system clock, IClock. See Ayende Rahien’s post on why this seeming non sequitur can be useful:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://ayende.com/Blog/archive/2008/07/07/Dealing-with-time-in-tests.aspx"&gt;http://ayende.com/Blog/archive/2008/07/07/Dealing-with-time-in-tests.aspx&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.claritycon.com/aggbug.aspx?PostID=102564" width="1" height="1"&gt;</description><category domain="http://blogs.claritycon.com/blogs/peter_miller/archive/tags/agile/default.aspx">agile</category></item><item><title>Making Visual Studio and Dependency Injection Play Nice</title><link>http://blogs.claritycon.com/blogs/peter_miller/archive/2010/01/14/making-visual-studio-and-dependency-injection-play-nice.aspx</link><pubDate>Fri, 15 Jan 2010 03:56:11 GMT</pubDate><guid isPermaLink="false">da947a97-509e-40e6-bbb5-1443ad47bf4e:102136</guid><dc:creator>pmiller</dc:creator><slash:comments>2</slash:comments><description>&lt;p&gt;Dependency injection (DI) is a powerful technique to make your code more testable and your application more adaptable to future changes. Working with an application that uses DI in Visual Studio can be painful. You want to be able to make changes to your dependencies, and have those changes automatically picked up and put in the right place, so that when your application tries to find them, it uses the latest version. And you want that all to happen just when you press F5 to debug.&lt;/p&gt;  &lt;p&gt;I posted a question to stackoverflow.com about this, laying out some options, including copying files by hand or creating a post build event per dependency per application. In keeping with stackoverflow rules about open ended questions, I quickly marked an answer as accepted. &lt;/p&gt;  &lt;p&gt;The answer I accepted was to change the output directories of the dependency projects to some common folder, which the application would then query for dependencies at runtime:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.claritycon.com/blogs/peter_miller/diBin_7CA73BAB.jpg"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="diBin" border="0" alt="diBin" src="http://blogs.claritycon.com/blogs/peter_miller/diBin_thumb_556CF276.jpg" width="357" height="161" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;This sounded good, but after some thought, I was worried about the unintended consequences of having these projects not build to the normal bin/debug, bin/release folders. &lt;/p&gt;  &lt;p&gt;After some experimentation, I ended up with a solution that is similar in spirit, but leaves the normal build output directory alone:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Add post build events to each dependency project to copy the dll and pdb files to a common directory      &lt;ol&gt;       &lt;li&gt;&lt;i&gt;xcopy&amp;#160; $(TargetDir)*.dll $(SolutionDir)diBin /iy            &lt;br /&gt;xcopy&amp;#160; $(TargetDir)*.pdb $(SolutionDir)diBin /iy&lt;/i&gt; &lt;/li&gt;     &lt;/ol&gt;   &lt;/li&gt;    &lt;li&gt;Add a post build event to the application project to copy the DI dll and pdb files to a subdirectory of its bin      &lt;ol&gt;       &lt;li&gt;&lt;i&gt;xcopy $(SolutionDir)\diBin\*.dll $(TargetDir)diBin\ /iy            &lt;br /&gt;xcopy $(SolutionDir)\diBin\*.pdb $(TargetDir)diBin\ /iy&lt;/i&gt; &lt;/li&gt;     &lt;/ol&gt;   &lt;/li&gt;    &lt;li&gt;We use Castle Windsor for DI and to see the dependency files in diBin\ I had to add this to the app.config:      &lt;ol&gt;       &lt;li&gt;&lt;i&gt;&amp;lt;runtime&amp;gt;            &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;assemblyBinding xmlns=&amp;quot;urn:schemas-microsoft-com:asm.v1&amp;quot;&amp;gt;             &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;probing privatePath=&amp;quot;diBin&amp;quot;/&amp;gt;             &lt;br /&gt;&amp;#160;&amp;#160; &amp;lt;/assemblyBinding&amp;gt;             &lt;br /&gt;&amp;lt;/runtime&amp;gt;&lt;/i&gt; &lt;/li&gt;     &lt;/ol&gt;   &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;All of the projects in our solution live one level below the solution, and all are solutions are in the same folder, so $(SolutionDir) is common.&lt;/p&gt;  &lt;p&gt;So far this has worked well. This does NOT solve anything having to do with deployment, but it does make the F5 debug experience much nicer.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Relevant Links:&lt;/p&gt;  &lt;p&gt;&lt;a&gt;Stack Overflow: How do I get a smooth debug experience in visual studio 2008 when using dependency injection?&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/823z9h8w(VS.80).aspx"&gt;MSDN documentation on the probing element&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.claritycon.com/aggbug.aspx?PostID=102136" width="1" height="1"&gt;</description><category domain="http://blogs.claritycon.com/blogs/peter_miller/archive/tags/smiles/default.aspx">smiles</category></item><item><title>We’re Hiring!</title><link>http://blogs.claritycon.com/blogs/jeff_smith/archive/2010/01/13/we-re-hiring.aspx</link><pubDate>Wed, 13 Jan 2010 15:51:52 GMT</pubDate><guid isPermaLink="false">da947a97-509e-40e6-bbb5-1443ad47bf4e:101883</guid><dc:creator>jdsmith</dc:creator><slash:comments>1</slash:comments><description>&lt;p align="justify"&gt;Ever wondered what it would be like to work for a fast-paced, award-winning consulting firm in Chicago? You’re in luck! We’re looking for a few exceptional people. &lt;/p&gt;  &lt;p align="justify"&gt;We’re generally less concerned with specific tool/language experience and more interested in a person’s interest and &lt;u&gt;proven&lt;/u&gt; ability to learn new tools and languages. That said, most of our candidates have several years’ experience developing software and most have worked with the .NET Framework and/or web development technologies in previous positions. &lt;/p&gt;  &lt;p align="justify"&gt;The majority of our openings are for full-time Consultant positions. Our Consultants wear many hats but are chiefly responsible for application design, development and deployment. Lots of opportunities for advancement.&lt;/p&gt;  &lt;p align="justify"&gt;Interested? Please send resumes to janet-at-claritycon-dot-com. &lt;/p&gt;  &lt;p align="justify"&gt;You can find more info on &lt;a href="http://www.claritycon.com/careers/" target="_blank"&gt;our career page&lt;/a&gt;!&lt;/p&gt;&lt;img src="http://blogs.claritycon.com/aggbug.aspx?PostID=101883" width="1" height="1"&gt;</description></item><item><title>Agile in Action - A Touch of Pair Programming</title><link>http://blogs.claritycon.com/blogs/peter_miller/archive/2010/01/10/agile-in-action-a-touch-of-pair-programming.aspx</link><pubDate>Sun, 10 Jan 2010 18:41:00 GMT</pubDate><guid isPermaLink="false">da947a97-509e-40e6-bbb5-1443ad47bf4e:101285</guid><dc:creator>pmiller</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;As a consultant, I am pulled in two seemingly opposing directions in regards to new technology. To be a good consultant, particularly at my company Clarity, you have to be engaged with technology. Reading, talking about, working with new technology is what keeps us fresh and relevant. Here I&amp;#39;m using technology to mean more then just languages or libraries, I also mean the processes and techniques of delivering quality software solutions. The &amp;quot;opposing&amp;quot; force I mentioned earlier is that we have to focus relentlessly on delivering the particular project we&amp;#39;re on, with its particular timelines and constraints. &lt;/p&gt;  &lt;p&gt;So while I constantly am tinkering with technology in my spare time, I have a much higher bar for what I&amp;#39;d include in my project work. For every upside something new promises, I have to decide if it outweighs the downside or risk to the project. With that said, for the past six months plus, I&amp;#39;ve been working in product development, so outside the context of my regular on site, client engagement. Our team still cares about the quality of our deliverable, but there is more freedom to experiment with new technology. Using my expanded definition of technology, our team has been experimenting with the new (to us) technology of agile processes.&lt;/p&gt;  &lt;p&gt;One of these processes is pair programming. Unfortunately, to the skeptic, a process where two people work together on the same machine on the same task, probably brings the following images to mind:&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;i&gt;The Guy Driving&lt;/i&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.claritycon.com/blogs/peter_miller/clip_image002_0805DFBE.jpg"&gt;&lt;img src="http://blogs.claritycon.com/blogs/peter_miller/clip_image002_thumb_605F6393.jpg" style="border-width:0px;display:inline;" title="clip_image002" alt="clip_image002" height="228" width="184" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;i&gt;The Other Dude&lt;/i&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.claritycon.com/blogs/peter_miller/clip_image004_000E3D5C.jpg"&gt;&lt;img src="http://blogs.claritycon.com/blogs/peter_miller/clip_image004_thumb_58D3F426.jpg" style="border-width:0px;display:inline;" title="clip_image004" alt="clip_image004" height="228" width="184" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;This is a mistaken view. First off, having worked previously in corporate IT, I can assure you that people are quite capable of doing nothing all day all by their lonesome. Second, we all value pair programming. Don&amp;#39;t believe me? Think about what you do when you are working on a particularly nasty bug or making a big architectural decision. You don&amp;#39;t usually do that alone, you bring in at least one other trusted person to help out, to bounce ideas off of. I&amp;#39;ve over simplified here, this is not what agile adherents really mean by pair programming. As an agile practice, pair programming is the predominant mode of work for developers. What I just described is just plain old collaboration. Nevertheless, it is important to point out that the argument is not about whether or not two people working together produce better results, it is about how often they should work together.&lt;/p&gt;  &lt;p&gt;Within our product team, we have not moved to pair programming for every task. But we have been using it more extensively then I have before. We&amp;#39;ve found it surprisingly effective over the past few weeks. In pair programming sessions each lasting a few hours, I and another team member were able to quickly get two components going from design to implementation. I was thrilled with the give and take as we reined in, revised and rejected each others&amp;#39; ideas as necessary. By the end of it, I was mentally worn out, but in a good, kind of post work out muscle burn type of way.&lt;/p&gt;  &lt;p&gt;With some hindsight, I think the key to this success was that we were truly peer programming, not just pair programming. There was no project role hierarchy to make one of us hesitant to correct the other, we have similar levels of tech skills and experience so we could keep up with each other and perhaps most importantly we respected each other. Respect means we take each other seriously and actually think about what the other one is saying or coding. This level of engagement helps both sides of the pair get more of out of the experience. Lack of respect plus malice is contempt, which obviously will not work well, but even lack of respect without dislike is often expressed as indifference or pity. Neither one is going to help the pair be more productive then its parts.&lt;/p&gt;  &lt;p&gt;Moving forward, I plan to use pair programming more often within our team. I am not ready to take the leap and say we should use it all the time. Part of the software development life cycle always involves some drudgery, linking up simple UI&amp;#39;s, writing DB scripts, fixing a simple bug and the like. These tasks might be more pleasant with a partner, but the possible gains in efficiency seem minimal.&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;Relevant Links&lt;/p&gt;  &lt;p&gt;&lt;a href="http://xprogramming.com/xpmag/whatisxp#pair"&gt;http://xprogramming.com/xpmag/whatisxp#pair&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://menloinnovations.com/blog/?p=399"&gt;http://menloinnovations.com/blog/?p=399&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://stackoverflow.com/questions/291630/does-pair-programming-work"&gt;http://stackoverflow.com/questions/291630/does-pair-programming-work&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.claritycon.com/aggbug.aspx?PostID=101285" width="1" height="1"&gt;</description><category domain="http://blogs.claritycon.com/blogs/peter_miller/archive/tags/agile/default.aspx">agile</category></item><item><title>Speaking at the Central Illinois SharePoint User Group on 1/21/2010</title><link>http://blogs.claritycon.com/blogs/george_durzi/archive/2009/12/29/speaking-at-the-central-illinois-sharepoint-user-group-on-1-21-2010.aspx</link><pubDate>Tue, 29 Dec 2009 16:53:00 GMT</pubDate><guid isPermaLink="false">da947a97-509e-40e6-bbb5-1443ad47bf4e:100434</guid><dc:creator>gdurzi</dc:creator><slash:comments>1</slash:comments><description>&lt;p&gt;I&amp;#39;ll be speaking at the Central Illinois SharePoint User Group in Springfield, IL&amp;nbsp;at 9:00AM on Thursday, January 21st 2010.&lt;/p&gt;
&lt;p&gt;The topic will be &lt;strong&gt;Building Communications Enabled Applications with OCS and Exchange&lt;/strong&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Office Communications Server 2007 R2 and Exchange 2010 enable the development of communication enabled applications more quickly and easily than ever before.&amp;nbsp; In this session you will learn about the core features included in the new platform SDKs and see a demo application built around a retail enterprise that utilizes each of the scenarios the platform enables.&amp;nbsp; You will also learn about opportunities for integrating OCS and Exchange into your SharePoint applications. &lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;More details on location and registration&amp;nbsp;areavailable at &lt;a href="https://www.clicktoattend.com/invitation.aspx?code=144377"&gt;https://www.clicktoattend.com/invitation.aspx?code=144377&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.claritycon.com/aggbug.aspx?PostID=100434" width="1" height="1"&gt;</description><category domain="http://blogs.claritycon.com/blogs/george_durzi/archive/tags/Community/default.aspx">Community</category></item><item><title>Clean &amp; Simple Control Styles for SILVERLIGHT 3</title><link>http://blogs.claritycon.com/blogs/design/archive/2009/12/21/clean-amp-simple-control-styles-for-silverlight-3.aspx</link><pubDate>Mon, 21 Dec 2009 23:23:49 GMT</pubDate><guid isPermaLink="false">da947a97-509e-40e6-bbb5-1443ad47bf4e:99880</guid><dc:creator>eklimczak</dc:creator><slash:comments>3</slash:comments><description>&lt;p&gt;I’ve been seeing a bunch of XAML based control skins for WPF and Silverlight lately and I can’t say I’m in love with any of them.&amp;#160; I was glad to see that the latest version of the &lt;a href="http://www.codeplex.com/Silverlight"&gt;SL toolkit&lt;/a&gt; has some &lt;a href="http://silverlight.codeplex.com/wikipage?title=Silverlight%20Toolkit%20Overview%20Part%203&amp;amp;referringTitle=Home&amp;amp;ANCHOR#TwilightBlueTheme"&gt;additional skins&lt;/a&gt; available, but again, I couldn’t see myself ever using the “Bubble Creme” or “Shiny Red” theme for a real client project.&amp;#160; Inspired by the &lt;a href="http://blog.nerdplusart.com/archives/silverlightsimplestyles"&gt;“Simple Styles” post&lt;/a&gt; by Robby Ingebretsen, I wanted to create a small set of styles that aren’t overly complicated but communicate a simple elegant look and feel.&amp;#160; Here at Clarity we put a ton of thought into creating clean and effective user interfaces so I thought I would share some of our techniques for accomplishing just that.&amp;#160; &lt;/p&gt; &lt;object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="700" height="450"&gt;  			&lt;param name="source" value="http://employees.claritycon.com/eklimczak/Blogs/SL3Skin/EbodaSkin.xap" /&gt;  			&lt;param name="onerror" value="onSilverlightError" /&gt;  			&lt;param name="background" value="white" /&gt;  			&lt;param name="minRuntimeVersion" value="2.0.31005.0" /&gt;  			&lt;param name="autoUpgrade" value="true" /&gt;  			&lt;a href="http://go.microsoft.com/fwlink/?LinkID=124807" style="text-decoration:none;"&gt;       			&lt;img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style:none;" /&gt;  			&lt;/a&gt;  &lt;/object&gt;  &lt;h3&gt;What does Clean &amp;amp; Simple Mean?&lt;/h3&gt;  &lt;p&gt;Clean User Interface design is typically characterized by a few consistent color choices, clear layout, and as few lines as possible.&amp;#160; And a set of nice control styles can go a long way in achieving a design that is complete and beautiful, not cluttered or overbearing.&amp;#160; Well designed control styles and skins are typically minimal in nature.&amp;#160; In other words, Minimalist design can be described as basic and stripped of superfluous elements, colors, shapes and textures.&amp;#160; For example, I think the controls below on the left (from the Silverlight toolkit) are relatively “over designed”&amp;#160; with excessive gradients and shiny textures.&amp;#160; On the other hand, the controls on the right (from Adobe Lightroom) have clean lines, color, and little texture and communicate the purpose of the control effectively.&amp;#160; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://employees.claritycon.com/eklimczak/a31168be5b1e_B97D/shiny.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="shiny" border="0" alt="shiny" src="http://employees.claritycon.com/eklimczak/a31168be5b1e_B97D/shiny_thumb.png" /&gt;&lt;/a&gt;&amp;#160;&amp;#160;&amp;#160; &lt;a href="http://employees.claritycon.com/eklimczak/a31168be5b1e_B97D/adobe.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="adobe" border="0" alt="adobe" src="http://employees.claritycon.com/eklimczak/a31168be5b1e_B97D/adobe_thumb.png" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h3&gt;How Do I Simplify My Design?&lt;/h3&gt;  &lt;p&gt;Designing a clean and minimal skin isn’t hard, but takes some trial and error before you get it “just right”.&amp;#160; Like I said earlier, well designed controls typically have little texture, color, shape and lines.&amp;#160; However, if you go too minimal the design becomes boring and incomplete.&amp;#160; To ensure that you are on the right path, keep in mind three fundamentals:&amp;#160; &lt;strong&gt;Be Mindful of Whitespace, Alignment, and Contrast.&lt;/strong&gt;&amp;#160; After applying these principles, take it a step further and try to take out everything that is unnecessary.&amp;#160;&amp;#160; Aside from the aforementioned basics, experimenting with different color combinations, atypical layout and interesting typography can help enhance the design while keeping it unique.&amp;#160;&amp;#160; &lt;/p&gt;  &lt;p&gt;Whether I’m designing a UI for an interactive display, digital display board, website, or desktop application I usually get started by:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Look for inspiration&amp;#160; - &lt;/strong&gt;There are tons of resources out there for creative inspiration.&amp;#160; Some I use are:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.designmeltdown.com/default.aspx"&gt;http://www.designmeltdown.com/default.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://veerle.duoh.com/blog"&gt;http://veerle.duoh.com/blog&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.designshard.com/"&gt;http://www.designshard.com/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Pick a color scheme&lt;/strong&gt; – I usually try to stick with a base of three colors (Primary, Secondary, Accent)&lt;/p&gt;  &lt;p&gt;&lt;a title="http://kuler.adobe.com" href="http://kuler.adobe.com"&gt;http://kuler.adobe.com&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.colourlovers.com/"&gt;http://www.colourlovers.com/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://colorblender.com/"&gt;http://colorblender.com/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Choose a font&lt;/strong&gt; – I usually keep a watchful eye for elegant, readable fonts. Then I use &lt;a href="http://new.myfonts.com/WhatTheFont/"&gt;WhatTheFont&lt;/a&gt; to help me track it down.&lt;/p&gt;  &lt;h3&gt;Building the UI&lt;/h3&gt;  &lt;p&gt;Below is a zoomed out view of a couple styled controls.&amp;#160; The important thing to notice is that the clickable regions look beveled and the right combination of lines create an “inset” look where appropriate.&amp;#160; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://employees.claritycon.com/eklimczak/a31168be5b1e_B97D/skin.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="skin" border="0" alt="skin" src="http://employees.claritycon.com/eklimczak/a31168be5b1e_B97D/skin_thumb.png" width="550" height="82" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;If we zoom in to 1200% we can see the anatomy of the button consists of three borders and a subtle gradient fill.&amp;#160; There aren’t any crazy multi-stop gradients or rasterized images used to create the beveled or inset effects…just rectangles and careful choice of color.&amp;#160; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://employees.claritycon.com/eklimczak/a31168be5b1e_B97D/zoom.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="zoom" border="0" alt="zoom" src="http://employees.claritycon.com/eklimczak/a31168be5b1e_B97D/zoom_thumb.png" width="548" height="236" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This technique of strategically placing lines to create subtle UI effects isn’t new.&amp;#160; In fact there are tons of examples done in Flash found all over the web and even in the windows and mac operating systems.&amp;#160; The iPhone, Palm-pre,&amp;#160; Adobe CS4, Garage Band, are just some examples of precise well-executed control styles.&amp;#160; &lt;/p&gt;  &lt;p&gt;For this post I choose Silevrlight 3 for demonstration purposes, but the design principles are technology agnostic and can be applied to any digital medium.&amp;#160; If you are interested in getting started with&amp;#160; control styling specifically in Silverlight 3, it would probably be a good idea to read up on using Resources, Control Templates, and the Visual State Manager in Blend.&amp;#160; I hope my post will be helpful in at least getting people started with creating their own elegant UI themes.&amp;#160; &lt;/p&gt;  &lt;p&gt;You can download the source for the above example &lt;a href="http://employees.claritycon.com/eklimczak/Blogs/SL3Skin/SL3_Skin.zip" target="_blank"&gt;HERE&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.claritycon.com/aggbug.aspx?PostID=99880" width="1" height="1"&gt;</description></item><item><title>VIDEO PROTOTYPING | A cost-effective and timely approach to application demonstrations.</title><link>http://blogs.claritycon.com/blogs/design/archive/2009/12/21/video-prototyping-a-cost-effective-and-timely-approach-to-application-demonstrations.aspx</link><pubDate>Mon, 21 Dec 2009 18:35:00 GMT</pubDate><guid isPermaLink="false">da947a97-509e-40e6-bbb5-1443ad47bf4e:99866</guid><dc:creator>blamb</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;When developing multi-touch applications we are often asked for a demonstration of how the final design solution is going to look and feel… or sometimes we just have a stellar idea that we need to share with everyone now! How do you accurately convey a complete user experience without building the entire application? Design mockups and storyboards alone are not going to cut it; they aren’t the most effective tools for communicating user interaction. When faced with a tight timeline or budget, our solution for rapid prototyping is video. &lt;/p&gt;  &lt;p&gt;&lt;b&gt;Demo Video vs Video Prototype      &lt;br /&gt;&lt;/b&gt;Although I recommend giving in person demos of your applications sometimes that just isn’t possible. Videos are a great substitute for in-person demos and in the age of You-Tube and Vimeo you have a much larger opportunity for reaching your target market. After an application is built we make a demo video highlighting the best features of the application by filming a user interacting with the application. A voiceover further describes the details of the application.&lt;/p&gt;  &lt;p&gt;Example of one of our demo videos, &lt;i&gt;The Gift Registry Surface Application&lt;/i&gt;&lt;/p&gt;  &lt;div style="margin:0px;padding:0px;display:inline;float:none;" id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:5dd249e8-fdfc-44ca-a3a8-177e656a9d58" class="wlWriterEditableSmartContent"&gt;&lt;div&gt;&lt;object height="355" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/IlNAOv75roQ&amp;amp;hl=en"&gt;&lt;embed src="http://www.youtube.com/v/IlNAOv75roQ&amp;amp;hl=en" type="application/x-shockwave-flash" height="355" width="425"&gt;&lt;/object&gt;&lt;/div&gt;&lt;/div&gt;  &lt;p&gt;You can see more of our demo videos at &lt;a href="http://www.claritycon.com/work/claritytv/"&gt;www.claritycon.com/work/claritytv/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The differentiating factor between the two is that prototyping requires the use of video as a design tool. Video is a fast way to visualize ideas and concepts without the need to spend endless hours developing an entire application. This method allows us to make simulations of real user interface functionality with simple equipment we have in-house. &lt;/p&gt;  &lt;p&gt;&lt;b&gt;Smoke and Mirrors      &lt;br /&gt;&lt;/b&gt;Video is a powerful tool, use it to your advantage. You are not bound to the limitations of technology, with green screens and compositing software the possibilities are endless. This process will let you explore new ways of interaction with software, hardware and technologies that don’t exist yet. If you think this method would be useful in your design process I have put together a HOW TO.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;How to Make a Video Prototype      &lt;br /&gt;&lt;/b&gt;Materials: Green screen material or basic green construction paper, adhesive (double sided tape works well), scissors, finished design mockups, camera, tripod, lights (main and fill), and after effects or equivalent. You will need basic knowledge of video editing and color keying, if you don’t its easy to pick up.&lt;/p&gt;  &lt;table cellpadding="0" cellspacing="0"&gt;     &lt;tr&gt;       &lt;td&gt;         &lt;p&gt;&lt;a href="http://blogs.claritycon.com/blogs/design/hardware_6A0DA244.jpg" target="_blank"&gt;&lt;img src="http://blogs.claritycon.com/blogs/design/hardware.jpg" alt="hardware" align="left" border="0" height="164" hspace="" width="244" /&gt;&lt;/a&gt; &lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;&lt;b&gt;&lt;font size="4"&gt;#1 Setup&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;          &lt;p&gt;Select your hardware. If you don’t have what you need be resourceful. For the project I will show we took apart a touch screen monitor, mounted a credit card swipe, a finger print scanner, and a tag reader (none of which actually worked together).&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;         &lt;p&gt;&lt;a href="http://blogs.claritycon.com/blogs/design/greenscreen_6A9722D9.jpg" target="_blank"&gt;&lt;img src="http://blogs.claritycon.com/blogs/design/greenscreen.jpg" alt="greenscreen" align="left" border="0" height="164" hspace="" width="244" /&gt;&lt;/a&gt; &lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;&lt;b&gt;&lt;font size="4"&gt;#2 Green Screen&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;          &lt;p&gt;Cut the green paper to the size of your screen and secure it to the screen with adhesive. Make sure there are as few as possible wrinkles or folds in the paper (you don’t want any shadows). If your surface is completely flat you may be able to get away with not using any adhesive.&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;         &lt;p&gt;&lt;a href="http://blogs.claritycon.com/blogs/design/light_3F528BD2.jpg" target="_blank"&gt;&lt;img src="http://blogs.claritycon.com/blogs/design/light.jpg" alt="light" align="left" border="0" height="164" hspace="" width="244" /&gt;&lt;/a&gt; &lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;&lt;b&gt;&lt;font size="4"&gt;#3 Lighting&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;          &lt;p&gt;Set up in an area that is well lit or preferably light the device yourself with the conventional 2 or 3 light setup. Lighting is very important when using green screen techniques. There should be no shadows on your green screened surface.&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;         &lt;p&gt;&lt;a href="http://blogs.claritycon.com/blogs/design/printout_063BAED0.jpg" target="_blank"&gt;&lt;img src="http://blogs.claritycon.com/blogs/design/printout.jpg" alt="printout" align="left" border="0" height="164" hspace="" width="244" /&gt;&lt;/a&gt; &lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;&lt;b&gt;&lt;font size="4"&gt;#4 Interface&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;          &lt;p&gt;Print out or sketch a large version of your mockup interface, it should be roughly the size of the green screened interface. Use this to set to the side for visual cues. This is helpful for making gestures and accurate selections on your interface. Make sure your print-out/sketch is not in your shot when filming!&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;         &lt;p&gt;&lt;a href="http://blogs.claritycon.com/blogs/design/storyboard_77DFE83F.jpg" target="_blank"&gt;&lt;img src="http://blogs.claritycon.com/blogs/design/storyboard.jpg" alt="storyboard" align="left" border="0" height="164" hspace="" width="244" /&gt;&lt;/a&gt; &lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;&lt;font size="4"&gt;&lt;b&gt;#5 Storyboards&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;          &lt;p&gt;Have your demo flow or user scenarios worked out before you start filming. Storyboards are great for this! Do a few practice runs using the green screen like it is a real life interface to work out gestures and any timing issues. It is helpful if you self narrate your demo. It keeps you from going too fast and you can keep it in the video or dub it out and record a cleaned-up version post-production.&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;         &lt;p&gt;&lt;a href="http://blogs.claritycon.com/blogs/design/straightangle_512F1F9F.jpg" target="_blank"&gt;&lt;img src="http://blogs.claritycon.com/blogs/design/straightangle.jpg" alt="straightangle" align="left" border="0" height="164" hspace="" width="244" /&gt;&lt;/a&gt; &lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;&lt;b&gt;&lt;font size="4"&gt;#6 Using the Camera&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;          &lt;p&gt;Set up your camera and film the demo at a straight-on angle. Repeat the same demo using a left or right-side angle. Multiple angles will provide you with plenty of footage for cuts and transitions. It doesn’t hurt to get an establishing shot of the environment as well as close-up shots of the application. Always use a tripod or some method of stabilizing the camera. Aim for shooting in HD if you can, it allows more room to scale and pan your footage while editing.&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;         &lt;p&gt;&lt;a href="http://blogs.claritycon.com/blogs/design/voiceover_1818429D.jpg" target="_blank"&gt;&lt;img src="http://blogs.claritycon.com/blogs/design/voiceover.jpg" alt="voiceover" align="left" border="0" height="164" hspace="" width="244" /&gt;&lt;/a&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;&lt;b&gt;&lt;font size="4"&gt;#7 Audio Recording&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;          &lt;p&gt;Sound can create a more immersive user experience. Record your sound effects, voice-over, or any other audio you may need for your prototype. Audacity is a great tool for audio recording. Remember that audio is a reusable asset and may be recycled for any future projects.&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;         &lt;p&gt;&lt;a href="http://blogs.claritycon.com/blogs/design/footage_5F01659A.jpg" target="_blank"&gt;&lt;img src="http://blogs.claritycon.com/blogs/design/footage.jpg" alt="footage" align="left" border="0" height="164" hspace="" width="244" /&gt;&lt;/a&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;&lt;font size="4"&gt;&lt;b&gt;#8 Compositing&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;          &lt;p&gt;Import video clips, audio, and Illustrator/Photoshop mockups into After Effects or other compositing software program. Your mockups should be organized by layers and named accordingly to make them easier to import. Edit your footage into sequence. Animate the mockups and sync audio to match the filmed interactions. Compose the live footage with the animated mockups, keying out the green.            &lt;br /&gt;            &lt;br /&gt;Finished example of a video prototype:&lt;i&gt; Blockbuster Checkout Experience&lt;/i&gt;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;         &lt;p&gt;&lt;a href="http://blogs.claritycon.com/blogs/design/colorkey_2EC3946F.jpg" target="_blank"&gt;&lt;img src="http://blogs.claritycon.com/blogs/design/colorkey.jpg" alt="colorkey" align="" border="0" height="164" hspace="" width="244" /&gt;&lt;/a&gt;&lt;/p&gt;          &lt;p&gt;&lt;a href="http://blogs.claritycon.com/blogs/design/compose_75ACB76C.jpg" target="_blank"&gt;&lt;img src="http://blogs.claritycon.com/blogs/design/compose.jpg" alt="compose" align="" border="0" height="164" hspace="" width="244" /&gt;&lt;/a&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;div style="margin:0px;padding:10px 0px 0px;width:425px;display:inline;float:left;" id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:0f16001c-1af1-4ad0-8b5e-eb1371f1f442" class="wlWriterEditableSmartContent"&gt;&lt;div&gt;&lt;object height="355" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/pm5VPbj_uDw&amp;amp;hl=en"&gt;&lt;embed src="http://www.youtube.com/v/pm5VPbj_uDw&amp;amp;hl=en" type="application/x-shockwave-flash" height="355" width="425"&gt;&lt;/object&gt;&lt;/div&gt;&lt;/div&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/table&gt;  &lt;p&gt;&lt;b&gt;Benefits&lt;/b&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Low cost, time efficient, and easy to do &lt;/li&gt;    &lt;li&gt;Allows you to consider the environment/setting &lt;/li&gt;    &lt;li&gt;Test out user scenarios that are limited by current technology &lt;/li&gt;    &lt;li&gt;Visualize design solutions with real interactions &lt;/li&gt;    &lt;li&gt;Identify design issues before any development occurs &lt;/li&gt;    &lt;li&gt;Learn new methods that are outside your realm of experience &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;b&gt;Limitations&lt;/b&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Few reusable assets      &lt;br /&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;What are you waiting for… Lights. Camera. Action!&lt;/p&gt;&lt;img src="http://blogs.claritycon.com/aggbug.aspx?PostID=99866" width="1" height="1"&gt;</description></item></channel></rss>