<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;CEEARHYyeyp7ImA9WxBbEEw.&quot;"><id>tag:blogger.com,1999:blog-7622136255348663693</id><updated>2010-03-07T17:44:05.893-08:00</updated><title>Love the Dot</title><subtitle type="html" /><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://www.lovethedot.net/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://www.lovethedot.net/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/7622136255348663693/posts/default?start-index=6&amp;max-results=5&amp;redirect=false&amp;v=2" /><author><name>Paul Jackson</name><uri>http://www.blogger.com/profile/07495739164094993738</uri><email>pjackson@lovethedot.net</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>42</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>5</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/LoveTheDot" /><feedburner:info uri="lovethedot" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><geo:lat>28.491653</geo:lat><geo:long>-81.264369</geo:long><entry gd:etag="W/&quot;C08BQXg-eip7ImA9WxBWF0s.&quot;"><id>tag:blogger.com,1999:blog-7622136255348663693.post-2360437932513166779</id><published>2010-02-09T16:30:00.001-08:00</published><updated>2010-02-09T16:30:50.652-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-02-09T16:30:50.652-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term=".Net 4.0" /><category scheme="http://www.blogger.com/atom/ns#" term="work of the devil" /><category scheme="http://www.blogger.com/atom/ns#" term="parallel computing" /><category scheme="http://www.blogger.com/atom/ns#" term="multi-threaded" /><category scheme="http://www.blogger.com/atom/ns#" term="Visual Studio 2010" /><category scheme="http://www.blogger.com/atom/ns#" term=".net" /><category scheme="http://www.blogger.com/atom/ns#" term="parallel extensions library" /><category scheme="http://www.blogger.com/atom/ns#" term="manycore" /><title>Parallel Programming in .Net 4.0 and VS2010: Part I – The Parallel Task Library (Parallel.For, Parallel.Foreach() and Invoke())</title><content type="html">&lt;p&gt;With the availability this week of the Visual Studio 2010 RC, it’s time to update the parallel posts from last year to cover changes in the API – so this is much the same information as presented in the &lt;a href="http://www.lovethedot.net/2009/01/parallel-programming-in-net-40-and.html" target="_blank"&gt;original article&lt;/a&gt;, but it’s updated for the Visual Studio 2010 release candidate.&lt;/p&gt;  &lt;p&gt;In this article, we’re going to look at the Parallel Task Library and what it makes available for parallelizing &lt;em&gt;for&lt;/em&gt; and &lt;em&gt;foreach&lt;/em&gt; loops.&lt;/p&gt;  &lt;h4&gt;Parallel.For()&lt;/h4&gt;  &lt;p&gt;Starting with a simple, single-threaded application that does some work a few times:&lt;/p&gt;  &lt;div style="border-bottom: gray 1px solid; border-left: gray 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; border-top: gray 1px solid; cursor: text; border-right: gray 1px solid; padding-top: 4px"&gt;   &lt;div style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;     &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; i = 0; i &amp;lt; 100; i++)&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;{&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    var watch = Stopwatch.StartNew();&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    doWork();&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    watch.Stop();&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    Console.WriteLine(&lt;span style="color: #006080"&gt;&amp;quot;{0} took {1} milliseconds&amp;quot;&lt;/span&gt;, i, watch.ElapsedMilliseconds);&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;}&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;Console.ReadLine();&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;And where the doWork() method is simply a really bad way of determining the prime numbers under 30000:&lt;/p&gt;

&lt;div style="border-bottom: gray 1px solid; border-left: gray 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; border-top: gray 1px solid; cursor: text; border-right: gray 1px solid; padding-top: 4px"&gt;
  &lt;div style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;
    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; doWork()&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt; {&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;     &lt;span style="color: #0000ff"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; i = 3; i &amp;lt; 30000; i++)&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;     {&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;         &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (isPrime(i))&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;             ;&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;     }&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt; }&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt; &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; isPrime(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; i)&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt; {&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;     &lt;span style="color: #0000ff"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; j = 2; j &amp;lt;= (i/2); j++)&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;     {&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;         &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; ((i % j) == 0)&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;             &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;     }&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;     &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt; }&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;The purpose of the doWork() method, of course, is just to give the CPU something to do – which it does, consistently taking about 147 milliseconds for each iteration on a system with a 2.27 GHz quadcore Q9100 processor.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh3.ggpht.com/_d6BPne4gY9w/S3H-KfqwIjI/AAAAAAAAAnI/GsfEoIzOVg0/s1600-h/image%5B2%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/_d6BPne4gY9w/S3H-KoX7GJI/AAAAAAAAAnM/U-Q1F6fnU14/image_thumb.png?imgmax=800" width="244" height="184" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Although there’s some activity on all four cores as this runs, the total CPU usage stays between 20% and 25%, never making full use of the processor’s four cores:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh4.ggpht.com/_d6BPne4gY9w/S3H-KxYHoLI/AAAAAAAAAnQ/5GfD4oqeXYc/s1600-h/image%5B6%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_d6BPne4gY9w/S3H-LO1ar3I/AAAAAAAAAnU/_bk2qF0z21Q/image_thumb%5B2%5D.png?imgmax=800" width="364" height="106" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Although the CPU and operating system will cooperate to send work from multiple applications to the cores in such a way as to make as much use of them as possible, a single-threaded application by itself will never get much above one core’s worth of the CPU’s total power.&amp;#160; &lt;/p&gt;

&lt;p&gt;To access that power for our applications, we have to create multiple threads – and .Net 4 makes it very easy to do so.&amp;#160; &lt;/p&gt;

&lt;p&gt;New in .Net 4 is the System.Threading.Tasks namespace which contains the Parallel class.&amp;#160; This new class has some static methods which allow us to change the code slightly to parallelize* it:&lt;/p&gt;

&lt;div style="border-bottom: gray 1px solid; border-left: gray 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; border-top: gray 1px solid; cursor: text; border-right: gray 1px solid; padding-top: 4px"&gt;
  &lt;div style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;
    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #008000"&gt;//for (int i = 0; i &amp;lt; 100; i++)&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;Parallel.For(0, 100, (i) =&amp;gt;&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    {&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        var watch = Stopwatch.StartNew();&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        doWork();&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        watch.Stop();&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        Console.WriteLine(&lt;span style="color: #006080"&gt;&amp;quot;{0} took {1} milliseconds&amp;quot;&lt;/span&gt;, i, watch.ElapsedMilliseconds);&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    }&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;);&lt;/pre&gt;
  &lt;/div&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;Parallel.For has multiple overloads, but at its most basic (above) it takes a &lt;em&gt;from&lt;/em&gt; integer (inclusive), a &lt;em&gt;to &lt;/em&gt;integer (exclusive) and a delegate (in this case a lambda expression).&amp;#160; The step defaults to 1.&lt;/p&gt;

&lt;p&gt;The effect of this small change is dramatic.&amp;#160; The CPU utilization will now spike to 100% when the application is run:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh4.ggpht.com/_d6BPne4gY9w/S3H-Ls4wQaI/AAAAAAAAAnY/tQbjlza897g/s1600-h/image%5B11%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/_d6BPne4gY9w/S3H-L8ckYOI/AAAAAAAAAnc/ZqFHzrvyxt4/image_thumb%5B5%5D.png?imgmax=800" width="336" height="92" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;And the total runtime for the 100 iterations drops from 14.7 seconds to 4.3 seconds – a huge increase in performance because we’re now making full use of the processor’s four cores.&lt;/p&gt;

&lt;p&gt;A look at the Visual Studio debugger’s Thread window (Debug | Windows | Threads) shows what made the difference.&amp;#160; When executing the first version of the code, with the traditional for-loop, only a single thread is executing at any one time:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh5.ggpht.com/_d6BPne4gY9w/S3H-MNuP2nI/AAAAAAAAAng/9G58NRZxP9s/s1600-h/image%5B16%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/_d6BPne4gY9w/S3H-MdOUpBI/AAAAAAAAAnk/Zl-EpLG5nzk/image_thumb%5B8%5D.png?imgmax=800" width="722" height="225" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;But the change to Parallel.For results in multiple threads doing the work:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh6.ggpht.com/_d6BPne4gY9w/S3H-M5iFgGI/AAAAAAAAAno/aRnAy9bAnU0/s1600-h/image%5B21%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_d6BPne4gY9w/S3H-NRXN4AI/AAAAAAAAAns/y8m-u0OQD8Y/image_thumb%5B11%5D.png?imgmax=800" width="733" height="314" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;In this case, five threads are simultaneously executing iterations of the work (the main application thread and four worker threads).&amp;#160; The exact number of threads used for parallelization is determined by .Net based on the number of cores available (there are some advanced options for controlling this, but careful consideration should be given before doing so).&lt;/p&gt;

&lt;p&gt;A comparison of the output of both versions does show a couple of important differences that you should consider before parallelizing your code:&lt;/p&gt;

&lt;table border="0" cellspacing="0" cellpadding="2" width="300"&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td valign="top" width="150"&gt;
        &lt;p align="center"&gt;&lt;a href="http://lh6.ggpht.com/_d6BPne4gY9w/S3H-Nv3KnnI/AAAAAAAAAnw/KDUq_h_qKfQ/s1600-h/image%5B24%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_d6BPne4gY9w/S3H-N0m1NQI/AAAAAAAAAn0/-FkHeOc-_kA/image_thumb%5B12%5D.png?imgmax=800" width="215" height="244" /&gt;&lt;/a&gt; for-loop&lt;/p&gt;
      &lt;/td&gt;

      &lt;td valign="top" width="150"&gt;
        &lt;p align="center"&gt;&lt;a href="http://lh3.ggpht.com/_d6BPne4gY9w/S3H-OARNwlI/AAAAAAAAAn4/ro5F-fec3zA/s1600-h/image%5B27%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/_d6BPne4gY9w/S3H-ObUG7wI/AAAAAAAAAn8/ZU6AJdQ6epc/image_thumb%5B13%5D.png?imgmax=800" width="216" height="244" /&gt;&lt;/a&gt; Parallel.For&lt;/p&gt;
      &lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;The first consideration is performance.&amp;#160; Although the total performance improved from 14-seconds to four, the time spent in each iteration has increased and become less predictable.&amp;#160; In a single-threaded, for-loop each iteration takes a consistent 147-milliseconds, but the parallel implementation varies from 147 to over 300-milliseconds.&amp;#160; This is due to overhead associated with the parallelization and the potential for threads to be swapped out by the operating system to provide CPU cycles to other applications.&lt;/p&gt;

&lt;p&gt;Another consideration is ordering of the work.&amp;#160; As you can see from the screenshots above, the single-threaded example performs the work sequentially.&amp;#160; Each time through the for loop does its work and completes before the next starts.&amp;#160; But when this is parallelized, the order of completion can’t be guaranteed.&amp;#160; As the work is off-loaded to seven worker threads (in this example), each of those threads could complete its work and get the next task at any time.&amp;#160; So parallelizing isn’t an option (or is a more complex option) when the order of execution matters to your application.&lt;/p&gt;

&lt;h4&gt;Parallel.ForEach&lt;/h4&gt;

&lt;p&gt;The Parallel.ForEach() method follows the same pattern:&lt;/p&gt;

&lt;div style="border-bottom: gray 1px solid; border-left: gray 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; border-top: gray 1px solid; cursor: text; border-right: gray 1px solid; padding-top: 4px"&gt;
  &lt;div style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;
    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;List&amp;lt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;&amp;gt; list = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; List&amp;lt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;&amp;gt;();&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #008000"&gt;// populate list&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;Parallel.ForEach(list, (item) =&amp;gt;&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    {&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #008000"&gt;// parallel work here&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    }&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;);&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;h4&gt;Parallel.Invoke&lt;/h4&gt;

&lt;p&gt;Parallel.For() and Parallel.ForEach() are useful if you have collections you need to act on or a known number of times you have to execute the same code, but what about when you have several different things (methods) you need to do?&amp;#160; For that, we have Parallel.Invoke().&lt;/p&gt;

&lt;p&gt;Parallel.Invoke() simply executes, in parallel, a list of methods passed to it:&lt;/p&gt;

&lt;div style="border-bottom: gray 1px solid; border-left: gray 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; border-top: gray 1px solid; cursor: text; border-right: gray 1px solid; padding-top: 4px"&gt;
  &lt;div style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;
    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;[] args)&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;{&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    Parallel.Invoke(A, B, C, D, E);&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    Console.ReadLine();&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;}&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; A(){}&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; B(){}&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; C(){}&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; D(){}&lt;/pre&gt;

    &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; E(){}&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Methods A(), B(), C(), D() and E() will be assigned to worker threads as they become available and execute in parallel.&amp;#160; As with the other methods, there are no guarantees about the order of execution.&lt;/p&gt;

&lt;h4&gt;Conclusion&lt;/h4&gt;

&lt;p&gt;The Parallel Extensions in .Net 4.0 are going give developers a much easier and consistent way to parallelize their applications.&amp;#160; The library greatly insulates us from the complexity and inner plumbing of the parallel world, but still have responsibilities to use them properly.&amp;#160; Hard questions and issues will remain around the architecture, design and implementation of parallelization in our applications, but Microsoft is aware of this and is busy providing us with more resources than just the tools in this library.&amp;#160; The &lt;a href="http://msdn.microsoft.com/en-us/concurrency/default.aspx"&gt;Parallel Computing Developer Center&lt;/a&gt; has a wealth of whitepapers and presentations on these topics.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lovethedot.s3.amazonaws.com/LoveTheDot.Demo.ParallelFor.zip" target="_blank"&gt;Source code for the Parallel.For example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;font size="1"&gt;* I’d really like to track down and &lt;strike&gt;beat&lt;/strike&gt; speak strongly to the &lt;strike&gt;bastard&lt;/strike&gt; person who coined the term “parallelize” because every time I talk about this feature I invariably drop a syllable and tell my audience how easy .Net 4 makes it for you to paralyze your code**.&lt;/font&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;font size="1"&gt;** On the other hand, if you don’t keep the pitfalls of &lt;strike&gt;the work of the devil&lt;/strike&gt; multi-threaded programming in mind, your code &lt;em&gt;will&lt;/em&gt; wind up paralyzed, so it’s still an accurate statement.&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7622136255348663693-2360437932513166779?l=www.lovethedot.net' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/kAUUvWSuAT7vTy0XTqb_nYO2TRw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/kAUUvWSuAT7vTy0XTqb_nYO2TRw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/kAUUvWSuAT7vTy0XTqb_nYO2TRw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/kAUUvWSuAT7vTy0XTqb_nYO2TRw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=O_FOpLq4OBE:yBB6c2hWtJ0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=O_FOpLq4OBE:yBB6c2hWtJ0:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=O_FOpLq4OBE:yBB6c2hWtJ0:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?i=O_FOpLq4OBE:yBB6c2hWtJ0:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=O_FOpLq4OBE:yBB6c2hWtJ0:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?i=O_FOpLq4OBE:yBB6c2hWtJ0:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=O_FOpLq4OBE:yBB6c2hWtJ0:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?i=O_FOpLq4OBE:yBB6c2hWtJ0:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=O_FOpLq4OBE:yBB6c2hWtJ0:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=O_FOpLq4OBE:yBB6c2hWtJ0:l6gmwiTKsz0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?d=l6gmwiTKsz0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=O_FOpLq4OBE:yBB6c2hWtJ0:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?i=O_FOpLq4OBE:yBB6c2hWtJ0:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=O_FOpLq4OBE:yBB6c2hWtJ0:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=O_FOpLq4OBE:yBB6c2hWtJ0:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=O_FOpLq4OBE:yBB6c2hWtJ0:KwTdNBX3Jqk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?i=O_FOpLq4OBE:yBB6c2hWtJ0:KwTdNBX3Jqk" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/LoveTheDot/~4/O_FOpLq4OBE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.lovethedot.net/feeds/2360437932513166779/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7622136255348663693&amp;postID=2360437932513166779" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7622136255348663693/posts/default/2360437932513166779?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7622136255348663693/posts/default/2360437932513166779?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/LoveTheDot/~3/O_FOpLq4OBE/parallel-programming-in-net-40-and.html" title="Parallel Programming in .Net 4.0 and VS2010: Part I – The Parallel Task Library (Parallel.For, Parallel.Foreach() and Invoke())" /><author><name>Paul Jackson</name><uri>http://www.blogger.com/profile/07495739164094993738</uri><email>pjackson@lovethedot.net</email><gd:extendedProperty name="OpenSocialUserId" value="17986907884361024776" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.lovethedot.net/2010/02/parallel-programming-in-net-40-and.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkEASXo7fyp7ImA9WxJSEkw.&quot;"><id>tag:blogger.com,1999:blog-7622136255348663693.post-775372382689909365</id><published>2009-05-01T14:50:00.001-07:00</published><updated>2009-05-01T14:50:48.407-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-01T14:50:48.407-07:00</app:edited><title>The Blogger Next Door - Update</title><content type="html">&lt;p&gt;It’s been about a month since I made my post about &lt;a href="http://www.lovethedot.net/2009/03/blogger-next-door.html"&gt;The Blogger Next Door&lt;/a&gt;, referring to Bil Simser’s &lt;a href="http://weblogs.asp.net/bsimser/archive/2009/03/27/the-girl-next-door.aspx"&gt;The Girl Next Door&lt;/a&gt; post – well, Bil has now posted an &lt;a href="http://weblogs.asp.net/bsimser/archive/2009/04/29/follow-up-the-girl-next-door-aka-laptop-for-nat.aspx"&gt;update&lt;/a&gt;, including pictures of Natalie receiving her new laptop with &lt;a href="http://www.nuance.com"&gt;Dragon Naturally Speaking&lt;/a&gt; at her birthday party this week.&amp;#160; On top of the laptop and software, Bil’s post raised $2100 to help Natalie’s family with the medical expenses.&amp;#160; &lt;/p&gt;  &lt;h2&gt;A Bit About Nuance Communications and Dragon Naturally Speaking&lt;/h2&gt;  &lt;p&gt;One of the things I find most impressive about the result is the actions of Nuance Communications, makers of &lt;a href="http://www.nuance.com"&gt;Dragon Naturally Speaking&lt;/a&gt;.&amp;#160; &lt;/p&gt;  &lt;p&gt;After reading Bil’s original post and making my own, I gave in to a bit of a whim and faxed a letter to the CEO of Nuance, referencing Bil’s blog and briefly describing the situation.&amp;#160; I faxed that letter after close of business on a Friday afternoon.&lt;/p&gt;  &lt;p&gt;Before 10:00 AM Monday morning, I had received an email from the Dragon Naturally Speaking Product Manager telling me that they had emailed Bil to offer a free copy of the software.&lt;/p&gt;  &lt;p&gt;They really didn’t have to respond at all and certainly not that quickly, but they did – and it wasn’t because of any great amount of publicity they’d get for the deed.&amp;#160; There were no national news vans hovering around this story – they did it because they were able to help and wanted to.&amp;#160; That’s the best reason.&lt;/p&gt;  &lt;p&gt;So, for what it’s worth coming from my little blog, the folks at Nuance are a stand-up group and I know I’ll be looking to them on any project I work on that might benefit from their products.&amp;#160;&amp;#160; &lt;/p&gt;&lt;div class="wlWriterHeaderFooter" style="text-align:left; margin:0px; padding:4px 4px 4px 4px;"&gt;&lt;script type="text/javascript"&gt;var dzone_url = 'http://www.lovethedot.net/2009/05/blogger-next-door-update.html';&lt;/script&gt;&lt;script type="text/javascript"&gt;var dzone_title = 'The Blogger Next Door - Update';&lt;/script&gt;&lt;script type="text/javascript"&gt;var dzone_blurb = 'The Blogger Next Door - Update';&lt;/script&gt;&lt;script type="text/javascript"&gt;var dzone_style = '2';&lt;/script&gt;&lt;script language="javascript" src="http://widgets.dzone.com/widgets/zoneit.js"&gt;&lt;/script&gt; &lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7622136255348663693-775372382689909365?l=www.lovethedot.net' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/BoMtOmHwzFy0s7QTCN0YhWhbrQU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/BoMtOmHwzFy0s7QTCN0YhWhbrQU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/BoMtOmHwzFy0s7QTCN0YhWhbrQU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/BoMtOmHwzFy0s7QTCN0YhWhbrQU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=iK4C8TMKN1c:bpiEGQxtOLc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=iK4C8TMKN1c:bpiEGQxtOLc:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=iK4C8TMKN1c:bpiEGQxtOLc:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?i=iK4C8TMKN1c:bpiEGQxtOLc:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=iK4C8TMKN1c:bpiEGQxtOLc:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?i=iK4C8TMKN1c:bpiEGQxtOLc:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=iK4C8TMKN1c:bpiEGQxtOLc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?i=iK4C8TMKN1c:bpiEGQxtOLc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=iK4C8TMKN1c:bpiEGQxtOLc:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=iK4C8TMKN1c:bpiEGQxtOLc:l6gmwiTKsz0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?d=l6gmwiTKsz0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=iK4C8TMKN1c:bpiEGQxtOLc:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?i=iK4C8TMKN1c:bpiEGQxtOLc:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=iK4C8TMKN1c:bpiEGQxtOLc:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=iK4C8TMKN1c:bpiEGQxtOLc:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=iK4C8TMKN1c:bpiEGQxtOLc:KwTdNBX3Jqk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?i=iK4C8TMKN1c:bpiEGQxtOLc:KwTdNBX3Jqk" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/LoveTheDot/~4/iK4C8TMKN1c" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.lovethedot.net/feeds/775372382689909365/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7622136255348663693&amp;postID=775372382689909365" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7622136255348663693/posts/default/775372382689909365?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7622136255348663693/posts/default/775372382689909365?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/LoveTheDot/~3/iK4C8TMKN1c/blogger-next-door-update.html" title="The Blogger Next Door - Update" /><author><name>Paul Jackson</name><uri>http://www.blogger.com/profile/07495739164094993738</uri><email>pjackson@lovethedot.net</email><gd:extendedProperty name="OpenSocialUserId" value="17986907884361024776" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.lovethedot.net/2009/05/blogger-next-door-update.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUABRnwzfip7ImA9WxJTF0g.&quot;"><id>tag:blogger.com,1999:blog-7622136255348663693.post-3288093551902655576</id><published>2009-04-26T07:55:00.001-07:00</published><updated>2009-04-26T07:55:57.286-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-26T07:55:57.286-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="email" /><title>Bulk Email Software</title><content type="html">&lt;p&gt;No, I haven’t turned SPAMmer.&amp;#160; &lt;/p&gt;  &lt;p&gt;But the company I work for has a need to send emails communications to its customers and the system we threw together in Java almost a decade ago just isn’t up to the current task.&amp;#160; It wasn’t even part of the original requirements for our website, we just decided it would be cool if we could send them emails so we built it in with a couple days’ effort.&lt;/p&gt;  &lt;p&gt;Over time, it’s become a critical communication tool and the slapped-together nature of the system is showing its age and limitations – so we started looking at options and came up with three basic possibilities:&amp;#160; enhance the current system, use a hosted service or buy desktop software.&lt;/p&gt;  &lt;p&gt;The basic requirements of the system are that we have around 26,000 customer email addresses and a half dozen opt-in news topics.&amp;#160; In addition, we send mandatory “alerts” to all customers, regardless of their opt-in decision – this is disclosed to them and is part of their membership agreement for using the website and the reason is that there are statutory and legal announcements that they have to receive in our business, so for these, they don’t get to say no.&lt;/p&gt;  &lt;p&gt;There are also some things that the current system doesn’t support which the business has requested over the years, or that would just be smart to do, so we also need a solution that will:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Support HTML emails.&amp;#160; The original system is text only and our communications are pretty dated at this point, being all text.&amp;#160; In fact, their appearance has more in common with Viagra ads than an email from a professional company.      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;We’d like a solution that doesn’t lock up midway through a send.&amp;#160; The current solution is written in Java running under IBM’s WebSphere and uses Enterprise JavaBeans – I’ll wait while those of you with experience in that realm shudder a bit – so it has some memory and performance issues.&amp;#160; One symptom of which is that it sometimes locks up and stops sending, but it doesn’t have a way to resume from where it stopped, so we wind up sending duplicates.&amp;#160; Like I said, we slapped this thing together ten years ago on a whim.      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;Better filtering.&amp;#160; Over time the business has asked to be able to send alerts to subsets of our customers, mostly based on geography.&amp;#160; The current system can’t do this, it’s only by type of customers and subscriptions – it doesn’t know which customers are in Florida or which are in particular counties.&amp;#160; I know this sounds trivial, but the nature of our data doesn’t make it easy – the web data actually doesn’t know about the customer data (where the address is), because they’re two different systems. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;And, finally, in case you hadn’t noticed, the economy &lt;em&gt;sucks&lt;/em&gt; right now and we’re in the real-estate sector, so cost is a big deal – we want something very, very inexpensive.&lt;/p&gt;  &lt;p&gt;There are pros and cons to each option – build it ourselves, use a hosted solution or buy desktop software.&amp;#160; &lt;/p&gt;  &lt;p&gt;Being a developer, I like the idea of writing my own solution.&amp;#160; That way, it does exactly what I want it to do the way I want it to do it.&amp;#160; (Okay, fine, in reality it does exactly what I &lt;em&gt;tell&lt;/em&gt; it to do in exactly the way I &lt;em&gt;coded&lt;/em&gt; it to do it, which isn’t &lt;em&gt;always &lt;/em&gt;what I “want”, but that’s a different post.)&amp;#160; But is this really the best use of the company’s resources if their are commercial products that will do the job?&amp;#160; That depends on the capabilities and cost, of course, which is why we do the build vs. buy evaluation.&lt;/p&gt;  &lt;p&gt;The online solutions look good, things like &lt;a href="http://www.constantcontact.com/index.jsp" target="_blank"&gt;Constant Contact&lt;/a&gt; – they meet all of the requirements except that they require opt-out from the list, something one type of mailing we have doesn’t allow.&amp;#160; Also, we’d fall in their $150 / month pricing bracket, so it might be more economical, in the long run, to just write it ourselves.&lt;/p&gt;  &lt;p&gt;That brought us to desktop solutions in our evaluation and we found &lt;a href="http://sendblaster.com/partners/jrox.php?id=1568_tlid_8_1_ADTRACKER" target="_blank"&gt;SendBlaster&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;SendBlaster definitely met our cost requirement – there’s a free version that sends 100 emails at a time or the purchased version that sends an unlimited number and the cost is a flat 75eu or about $100.&amp;#160; &lt;/p&gt;  &lt;div style="float: right"&gt;&lt;a href="http://sendblaster.com/partners/jrox.php?id=1568_tlid_8_1_ADTRACKER"&gt;&lt;img title="Email blast software mass email sending for email marketing" alt="Email blast software mass email sending for email marketing" src="http://www.sendblaster.com/bulk-email-software/wp-content/email-blast-software.gif" /&gt;&lt;/a&gt;&lt;/div&gt;  &lt;p&gt;It supports HTML emails and hasn’t locked up at all during testing – and if it ever does, it can resume a mailing from where it left off.&lt;/p&gt;  &lt;p&gt;SendBlaster has some nice import/export features that will let us run queries to or even create a web page to get customers into/out-of the lists and supports an unlimited number of lists, so we can have one list for each of the news topics we allow our customers to subscribe to and one that includes all of them for the mandatory emails.&lt;/p&gt;  &lt;p&gt;SendBlaster satisfies most of what the business wants for geographic filtering, too.&amp;#160; We can import our customers’ state, zipcode and county and filter the list based on these.&amp;#160; This will allow us to stop sending Florida emails to customers in other states.&lt;/p&gt;  &lt;p&gt;For $100, we really can’t go wrong with this software – if it turns out not to work well for us, we’ve spent less than one month of an online service charge or less than it would cost to put four people in a room for an hour to talk about writing our own.&lt;/p&gt;&lt;div class="wlWriterHeaderFooter" style="text-align:left; margin:0px; padding:4px 4px 4px 4px;"&gt;&lt;script type="text/javascript"&gt;var dzone_url = 'http://www.lovethedot.net/2009/04/bulk-email-software.html';&lt;/script&gt;&lt;script type="text/javascript"&gt;var dzone_title = 'Bulk Email Software';&lt;/script&gt;&lt;script type="text/javascript"&gt;var dzone_blurb = 'Bulk Email Software';&lt;/script&gt;&lt;script type="text/javascript"&gt;var dzone_style = '2';&lt;/script&gt;&lt;script language="javascript" src="http://widgets.dzone.com/widgets/zoneit.js"&gt;&lt;/script&gt; &lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7622136255348663693-3288093551902655576?l=www.lovethedot.net' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/nD7P_H12qQsd3ykk4JONDKrol7w/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/nD7P_H12qQsd3ykk4JONDKrol7w/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/nD7P_H12qQsd3ykk4JONDKrol7w/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/nD7P_H12qQsd3ykk4JONDKrol7w/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=6naXzR0XEQ8:_ctFjkuLoEo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=6naXzR0XEQ8:_ctFjkuLoEo:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=6naXzR0XEQ8:_ctFjkuLoEo:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?i=6naXzR0XEQ8:_ctFjkuLoEo:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=6naXzR0XEQ8:_ctFjkuLoEo:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?i=6naXzR0XEQ8:_ctFjkuLoEo:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=6naXzR0XEQ8:_ctFjkuLoEo:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?i=6naXzR0XEQ8:_ctFjkuLoEo:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=6naXzR0XEQ8:_ctFjkuLoEo:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=6naXzR0XEQ8:_ctFjkuLoEo:l6gmwiTKsz0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?d=l6gmwiTKsz0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=6naXzR0XEQ8:_ctFjkuLoEo:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?i=6naXzR0XEQ8:_ctFjkuLoEo:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=6naXzR0XEQ8:_ctFjkuLoEo:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=6naXzR0XEQ8:_ctFjkuLoEo:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=6naXzR0XEQ8:_ctFjkuLoEo:KwTdNBX3Jqk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?i=6naXzR0XEQ8:_ctFjkuLoEo:KwTdNBX3Jqk" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/LoveTheDot/~4/6naXzR0XEQ8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.lovethedot.net/feeds/3288093551902655576/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7622136255348663693&amp;postID=3288093551902655576" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7622136255348663693/posts/default/3288093551902655576?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7622136255348663693/posts/default/3288093551902655576?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/LoveTheDot/~3/6naXzR0XEQ8/bulk-email-software.html" title="Bulk Email Software" /><author><name>Paul Jackson</name><uri>http://www.blogger.com/profile/07495739164094993738</uri><email>pjackson@lovethedot.net</email><gd:extendedProperty name="OpenSocialUserId" value="17986907884361024776" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://www.lovethedot.net/2009/04/bulk-email-software.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0QARHYzcCp7ImA9WxVaFkg.&quot;"><id>tag:blogger.com,1999:blog-7622136255348663693.post-6098298383639177056</id><published>2009-04-13T14:49:00.001-07:00</published><updated>2009-04-13T14:49:05.888-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-13T14:49:05.888-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="movies" /><category scheme="http://www.blogger.com/atom/ns#" term="media center" /><category scheme="http://www.blogger.com/atom/ns#" term="television" /><title>Two Years Without Television – Windows Media Center and Streaming Alternatives to Cable</title><content type="html">&lt;p&gt;March marked two years since I stopped paying for cable or satellite television.&amp;#160; No, I didn’t string a cable from the neighbor’s box, neither did I give up watching movies and television shows altogether – I simply stopped paying cable and satellite providers for content that was already being paid for via advertising.&lt;/p&gt;  &lt;p&gt;At the time I made the decision to do this I’d noticed that most of the programs I watched were made available on DVD at some point, and that I’d almost always rent the DVDs to catch up on missed episodes; also, online alternatives were becoming more prevalent, so what was the point in paying exorbitant cable or satellite fees?&lt;/p&gt;  &lt;p&gt;So I set about building a &lt;a href="http://www.microsoft.com/windows/windows-vista/features/media-center.aspx" target="_blank"&gt;Windows Media Center&lt;/a&gt; PC and, since I’m lazy, ripping all my DVDs so I wouldn’t have to get off the couch to watch one.&amp;#160; Actually, Media Center wasn’t my first choice – I was originally going to simply build a file server and get a media extender device, &lt;a href="http://www.dlink.com/products/category.asp?cid=75&amp;amp;sec=1" target="_blank"&gt;like those from DLink&lt;/a&gt;.&amp;#160; In fact, my first purchase toward this goal was a DLink DSM-320RD.&amp;#160; &lt;/p&gt;  &lt;p&gt;The 320 worked wonderfully for streaming music, but I soon found problems with video, especially DVD-quality video and the device’s interface.&amp;#160; The way these devices typically work is that video is streamed from a PC to the device, so the server software is important.&amp;#160; After trying the software that came with the 320, the compatible software from &lt;a href="http://www.nero.com/enu/mediahome4-introduction.html" target="_blank"&gt;Nero&lt;/a&gt; and the free &lt;a href="http://tversity.com/" target="_blank"&gt;TVersity&lt;/a&gt;, I finally gave up on the dedicated-device solution and decided to hook a PC directly to the television.&lt;/p&gt;  &lt;h4&gt;Base Hardware&lt;/h4&gt;  &lt;p&gt;One nice thing about building a Media Center PC these days is that you don’t need to get the latest, fastest hardware in order to make it work.&amp;#160; Ultimately all it’s doing is playing video, so there’s not a lot of horsepower required.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Intel Dual-Core 1.6GHz      &lt;br /&gt;2 GB       &lt;br /&gt;On-board 256 MB Video with DVI connector       &lt;br /&gt;300 GB Main Drive       &lt;br /&gt;&lt;a href="http://us.creative.com/products/product.asp?category=1&amp;amp;subcategory=206&amp;amp;product=10702&amp;amp;listby=" target="_blank"&gt;SoundBlaster Live! 24-bit External&lt;/a&gt;       &lt;br /&gt;&lt;a href="http://www.amazon.com/gp/product/B000W5GK5C?ie=UTF8&amp;amp;tag=montalia&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=B000W5GK5C"&gt;Media Center Remote&lt;/a&gt;&lt;img style="margin: 0px; border-top-style: none! important; border-right-style: none! important; border-left-style: none! important; border-bottom-style: none! important" height="1" alt="" src="http://www.assoc-amazon.com/e/ir?t=montalia&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=B000W5GK5C" width="1" border="0" /&gt;       &lt;br /&gt;&lt;a href="http://www.amazon.com/gp/product/B0009V6TL4?ie=UTF8&amp;amp;tag=montalia&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=B0009V6TL4"&gt;Wireless Keyboard and Mouse&lt;/a&gt;&lt;img style="margin: 0px; border-top-style: none! important; border-right-style: none! important; border-left-style: none! important; border-bottom-style: none! important" height="1" alt="" src="http://www.assoc-amazon.com/e/ir?t=montalia&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=B0009V6TL4" width="1" border="0" /&gt; &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This has proven to be plenty of power, even with some other things I run on the system, which we’ll get to in a bit.&lt;/p&gt;  &lt;h4&gt;&lt;/h4&gt;  &lt;h4&gt;Television&lt;/h4&gt;  &lt;p&gt;I started with a 42” Mitusbishi real-projection television that we already had.&amp;#160; In fact, this is the reason I chose a motherboard that had &lt;a href="http://en.wikipedia.org/wiki/Digital_Visual_Interface" target="_blank"&gt;DVI&lt;/a&gt; out for the video, instead of &lt;a href="http://en.wikipedia.org/wiki/HDMI" target="_blank"&gt;HDMI&lt;/a&gt;.&amp;#160; Though HDMI was newer and better, the existing television, that was already a few years old, didn’t support it, so I went with DVI.&amp;#160; &lt;/p&gt;  &lt;p&gt;After connecting the television and the PC, I ran into the problem of &lt;a href="http://en.wikipedia.org/wiki/Overscan" target="_blank"&gt;overscan&lt;/a&gt;, or the fact that tube and projection televisions project outside the border of the television itself.&amp;#160; This is somewhat incompatible with computer video, so some of the desktop was cut off along the four sides.&amp;#160; Media Center adjusts for this phenomena, but the Windows desktop doesn’t, making the experience fine in Media Center, but rather awkward using the browser.&lt;/p&gt;  &lt;p&gt;Last year I replaced the television with an LCD – since LCD’s don’t have an overscan problem, I now have a true 1080p desktop.&amp;#160; &lt;/p&gt;  &lt;h4&gt;Software&lt;/h4&gt;  &lt;p&gt;Everything you really need is included in Windows &lt;a href="http://www.microsoft.com/windows/windows-vista/default.aspx" target="_blank"&gt;Vista&lt;/a&gt; Home Premium or Ultimate.&amp;#160; There are a lot of people out there who still use &lt;a href="http://www.microsoft.com/WindowsXP/mediacenter/default.mspx" target="_blank"&gt;XP Media Center Edition&lt;/a&gt;, but I’ve been running Vista for two years now and haven’t had a single problem that was Vista’s fault.&amp;#160; That being said, I’ll still be switching to Windows 7 Media Center, because of the &lt;a href="http://blog.retrosight.com/WindowsMediaCenterInThePDCBuildOfWindows7.aspx" target="_blank"&gt;new features&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;A nice thing about Media Center, though, is that it’s extensible and there are two plugins that are essential. &lt;/p&gt;  &lt;div style="float: right"&gt;&lt;a href="http://lh4.ggpht.com/_d6BPne4gY9w/SeOzScovpOI/AAAAAAAAAkA/W8pujZgyz1U/s1600-h/MyNetflix22Small_WatchNowGenre%5B8%5D.jpg"&gt;&lt;img title="MyNetflix22Small_WatchNowGenre" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="172" alt="MyNetflix22Small_WatchNowGenre" src="http://lh5.ggpht.com/_d6BPne4gY9w/SeOzSrHj0mI/AAAAAAAAAkE/f5edz9MGEHM/MyNetflix22Small_WatchNowGenre_thumb%5B4%5D.jpg?imgmax=800" width="295" border="0" /&gt;&lt;/a&gt;&lt;/div&gt;  &lt;p&gt;First, is the &lt;a href="http://www.anpark.com/Software.aspx" target="_blank"&gt;MyNetflix plugin&lt;/a&gt;, written by Anthony Park.&amp;#160; Obviously, since my goal was to replace cable and satellite with online and DVD, &lt;a href="http://www.netflix.com/" target="_blank"&gt;Netflix&lt;/a&gt; was a critical component to my solution, but beyond the mailed DVDs is the Watch Now feature of Netflix.&amp;#160; The MyNetflix plugin provides a Media Center interface to Watch Now, allowing you to browse, search and view Watch Now offerings from within Media Center.&lt;/p&gt;  &lt;p&gt;You can also browse your mail queue and search for movies, adding them to your mail or Watch Now queues with a Media Center remote.&lt;/p&gt;  &lt;p&gt;MyNetflix is free, but donations are accepted.&amp;#160; &lt;/p&gt;  &lt;div style="float: right"&gt;&lt;a href="http://lh3.ggpht.com/_d6BPne4gY9w/SeOzTV569QI/AAAAAAAAAkI/KnnlPd_haRc/s1600-h/MyMovies%5B4%5D.png"&gt;&lt;img title="MyMovies" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="198" alt="MyMovies" src="http://lh4.ggpht.com/_d6BPne4gY9w/SeOzUB3U08I/AAAAAAAAAkM/ulid5CbWers/MyMovies_thumb%5B2%5D.png?imgmax=800" width="302" border="0" /&gt;&lt;/a&gt;&lt;/div&gt;  &lt;p&gt;The second essential plugin is &lt;a href="http://www.mymovies.dk/" target="_blank"&gt;My Movies&lt;/a&gt; from Binnerup Consulting.&amp;#160; My Movies is important to me because it helps organize my DVD collection and plays them from the hard drive.&amp;#160; &lt;/p&gt;  &lt;p&gt;My Movies has tons of features, including a comprehensive database of DVD information – front and back cover art, cast and crew, categories, and descriptions.&amp;#160; All of this is searchable and browsable through the Media Center interface, so you can, for instance, find all the movies you have that star a particular actor.&lt;/p&gt;  &lt;p&gt;My Movies manages a DVD collection whether you rip them to hard drive or not and supports several DVD carousels.&amp;#160; Even without having the DVD online, it’s nice to have a database of your collection and My Movies also allows you to export your collection data to a website provided by Binnerup – &lt;a href="http://c.mymovies.name/jackson" target="_blank"&gt;here’s mine&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Getting movies into My Movies is easy, the software can recognize a DVD when it’s inserted into the drive by its Disc ID.&amp;#160; Alternatively you can enter its barcode or scan the barcode with a webcam, search the main My Movies database by title, or enter the data manually.&amp;#160; That last option is useful for entering your own videos – for instance I have all of my family’s Christmas and birthday videos, as well as my daughter’s dance recitals, as part of the collection, so when someone visits I can just browse to these with the remote and show hours of family videos … &lt;/p&gt;  &lt;p&gt;There’s also a &lt;a href="http://www.mymovies.dk/forum.aspx?g=posts&amp;amp;t=9151" target="_blank"&gt;My Movies client&lt;/a&gt;, written by a third-party, that can access the My Movies database from any Windows client, even without Media Center.&amp;#160; I put this on my son’s XP system so he can watch movies in his room.&amp;#160; With My Movies and this client, my original DVD discs remain safely stored away, no matter how many times he wants to watch &lt;a href="http://www.starwars.com/" target="_blank"&gt;Star Wars&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;My Movies is also free, with donations accepted.&lt;/p&gt;  &lt;p&gt;One change I’ve made to my Vista configuration is to &lt;a href="http://www.missingremote.com/index.php?option=com_content&amp;amp;task=view&amp;amp;id=1220&amp;amp;Itemid=224" target="_blank"&gt;enable multiple Remote Desktop Sessions&lt;/a&gt; – this is a hack that lets me access the Media Center PC remotely while it’s also running a session on the television.&amp;#160; This allows me to use the Media Center PC to perform other tasks even while I’m watching something.&amp;#160; What tasks?&amp;#160; Well, I’ve used it to capture and process video from old VHS tapes, download large files, even to rip a new DVD while watching a different movie – the CPU isn’t really struggling to play video, either streaming or from a file, so there’s plenty of processing power available for me to use.&lt;/p&gt;  &lt;h4&gt;&lt;/h4&gt;  &lt;h4&gt;Ripping DVDs&lt;/h4&gt;  &lt;p&gt;I use two programs from Slysoft for ripping DVDs: &lt;a href="http://www.slysoft.com/en/anydvd.html" target="_blank"&gt;AnyDVD&lt;/a&gt; and &lt;a href="http://www.slysoft.com/en/clonedvd.html" target="_blank"&gt;CloneDVD&lt;/a&gt;.&amp;#160; This combination allows me to rip just the title and audio tracks I want, leaving behind the trailers, menus, special features and other languages.&amp;#160; Doing this reduces the amount of space necessary to store the main title, which is what I typically watch anyway – if I want to watch a special feature, I can always dig the original disc out of storage.&lt;/p&gt;  &lt;p&gt;This space savings is important to me – a typical DVD, with all features and sound, runs upwards of 7GB, but stripped of non-essentials, they average between three and six.&amp;#160; One or two gigs may not seem like a lot to save, but added up over four hundred titles, it becomes significant.&lt;/p&gt;  &lt;h4&gt;Storage&lt;/h4&gt;  &lt;p&gt;I went ‘round-and-‘round on the storage issue at the beginning, debating between internal storage and external.&amp;#160; Remember my original intent was to build a file server and stream to a media device, so internal storage made sense, but when I changed my mind on that it also changed the storage solution.&lt;/p&gt;  &lt;p&gt;With a streaming solution, I could put the file server in a back room or closet, which would solve two problems: dirt and noise.&amp;#160; See there are three dogs and nine cats in my house … yeah, I know … so dust and hair are issues.&amp;#160; A lot of internal drives would mean a case with a lot of fans, and a lot of fans add up to two things: noise and openings in the case.&amp;#160; Having that amount of fan and drive noise in my living room when I’m trying to enjoy a movie wasn’t optimal – neither was having a case with so many infiltration points for dust and hair.&amp;#160; &lt;/p&gt;  &lt;p&gt;I could have built two systems, and may take that route one day, but I also wanted to keep startup costs low and build up drive space over time as I expanded my library, so I went with external drives.&amp;#160; The current storage solution is made up of:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a href="http://www.amazon.com/gp/product/B001RB1QWW?ie=UTF8&amp;amp;tag=montalia&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=B001RB1QWW"&gt;Western Digital My Book World Edition 1 TB Network Attached Storage (quantity 2)&lt;/a&gt;&lt;img style="margin: 0px; border-top-style: none! important; border-right-style: none! important; border-left-style: none! important; border-bottom-style: none! important" height="1" alt="" src="http://www.assoc-amazon.com/e/ir?t=montalia&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=B001RB1QWW" width="1" border="0" /&gt;       &lt;br /&gt;&lt;a href="http://www.amazon.com/gp/product/B000VZCEUI?ie=UTF8&amp;amp;tag=montalia&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=B000VZCEUI"&gt;Western Digital My Book Essential Edition 1 TB USB 2.0 External Hard Drive&lt;/a&gt;&lt;img style="margin: 0px; border-top-style: none! important; border-right-style: none! important; border-left-style: none! important; border-bottom-style: none! important" height="1" alt="" src="http://www.assoc-amazon.com/e/ir?t=montalia&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=B000VZCEUI" width="1" border="0" /&gt;       &lt;br /&gt;&lt;a href="http://www.amazon.com/gp/product/B001D7REJ4?ie=UTF8&amp;amp;tag=montalia&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=B001D7REJ4"&gt;Iomega Prestige 1 TB USB 2.0 Desktop External Hard Drive&lt;/a&gt;&lt;img style="margin: 0px; border-top-style: none! important; border-right-style: none! important; border-left-style: none! important; border-bottom-style: none! important" height="1" alt="" src="http://www.assoc-amazon.com/e/ir?t=montalia&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=B001D7REJ4" width="1" border="0" /&gt; &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The World Books attach directly to the network and the USB drives hang off of them, giving me 4TB of storage on the network.&amp;#160; All the drives were acquired over the last two years by carefully scouring sales, closeouts and store-closings, so I was able to pick them up for much less than the normal price, making it a pretty cheap 4TB.&lt;/p&gt;  &lt;p&gt;On a separate note, I think it’s utterly amazing that we live in a world where I can have 4TB of data storage in my house.&amp;#160; To put it in perspective, when I bought my first hard drive, a 20MB drive for my Apple IIgs, it cost around $600 – today, for less than that, I have 4TB just for digital media.&amp;#160; I can’t imagine what will be available in another twenty years or what we’ll use it for … it’s amazing.&lt;/p&gt;  &lt;h4&gt;Network&lt;/h4&gt;  &lt;p&gt;I quickly found that wireless simply wasn’t fast or reliable enough to serve video in my environment, so I had to string some cable.&amp;#160; My house has steel studs and wireless has always been a challenge here.&amp;#160; I took the opportunity, while up in the attic, to drop cables into the kids’ rooms as well, so now the only computers not wired are the laptops.&amp;#160; Since they’re usually in the same place all the time, I may break down and string some cable for them, too, leaving the wireless solely for visitors.&amp;#160; From a security-standpoint, I like this idea, too.&lt;/p&gt;  &lt;h4&gt;&lt;/h4&gt;  &lt;h4&gt;Streaming&lt;/h4&gt;  &lt;p&gt;In addition to DVDs, the Internet a source for me to find video content, with &lt;a href="http://www.hulu.com/" target="_blank"&gt;Hulu&lt;/a&gt; and &lt;a href="http://www.fancast.com" target="_blank"&gt;FanCast&lt;/a&gt; being my favorites.&amp;#160; Although there isn’t an official Media Center plugin available for either site, there is a &lt;a href="http://www.secondrun.tv/default.asp?action=drawpage&amp;amp;pageid=22" target="_blank"&gt;third-party option&lt;/a&gt; in beta.&amp;#160; The &lt;a href="http://www.secondrun.tv/default.asp?action=drawpage&amp;amp;pageid=22" target="_blank"&gt;SecondRun.tv&lt;/a&gt; plugin doesn’t only work with Hulu and Fancast, but other providers as well. &lt;/p&gt;  &lt;p&gt;SecondRun has an advantage in that it’s network- and show-based, so content from multiple sources is aggregated based on the program or network, not the streaming provider.&amp;#160; A disadvantage is that, since it’s not provider-based, you have to browse for shows, rather than setting up your Hulu queue and playing that.&lt;/p&gt;  &lt;p&gt;I like SecondRun for browsing shows … a lot … but I still want a Hulu plugin for Media Center so that my subscriptions will just show up in my queue.&lt;/p&gt;  &lt;p&gt;In the meantime, I’ll simply use a browser.&amp;#160; With Vista set to a large font and a wireless keyboard/mouse, the browser has a decent &lt;a href="http://digital-lifestyle.aol.com/video/faqs/faqarticle/_a/what-is-the-media-center-pc-ten-foot/20061003133009990002" target="_blank"&gt;ten-foot experience&lt;/a&gt;.&amp;#160; I can live with it until someone (or me) gets fed up and writes a plugin that accesses the queue.&lt;/p&gt;  &lt;h4&gt;Done&lt;/h4&gt;  &lt;p&gt;So that’s it … two years with no cable or satellite bill, I figure that’s saved me close to a couple thousand dollars, more than paying for the hardware.&amp;#160; The Netflix subscription has a fee, but I’d have been paying that anyway to get new movies to watch, so it’s a wash.&lt;/p&gt;  &lt;p&gt;It’s a little different – with some shows there’s a delay before they’re available online, so I’m not always “up-to-date” when talking to others about the show, and I’m a year behind if I wait for the DVDs; but even that has advantages, because I can sit down with the full set of DVDs and watch an entire season without having to wait a week between episodes.&amp;#160; I like that.&lt;/p&gt;  &lt;p&gt;I really think streaming is the future and sites like Hulu and FanCast have it right – on-demand content supported by advertising.&amp;#160; I’m okay with the ads because they pay for the show and they’re shorter and fewer than in broadcast television.&amp;#160; In fact, I’m looking forward to the day when one of those sites ties the viewer’s profile to the ad-server, so the ads can be targeted better.&amp;#160; Like Google Adwords, being able to target specific markets, instead of just everyone who watches a show, will make the ads more valuable – which translates into fewer ads being necessary and better content … and maybe seeing ads that the viewer’s actually interested in.&lt;/p&gt;  &lt;p&gt;As more content moves online, and more viewers realize they have options other than the traditional cable and satellite companies, it’ll be interesting to see how those companies react to the changing market.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7622136255348663693-6098298383639177056?l=www.lovethedot.net' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Wjn2vfdDfZIQbAoNv1WtWGei33Q/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Wjn2vfdDfZIQbAoNv1WtWGei33Q/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Wjn2vfdDfZIQbAoNv1WtWGei33Q/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Wjn2vfdDfZIQbAoNv1WtWGei33Q/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=nY_HksDtBJ4:023SjOa34uU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=nY_HksDtBJ4:023SjOa34uU:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=nY_HksDtBJ4:023SjOa34uU:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?i=nY_HksDtBJ4:023SjOa34uU:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=nY_HksDtBJ4:023SjOa34uU:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?i=nY_HksDtBJ4:023SjOa34uU:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=nY_HksDtBJ4:023SjOa34uU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?i=nY_HksDtBJ4:023SjOa34uU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=nY_HksDtBJ4:023SjOa34uU:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=nY_HksDtBJ4:023SjOa34uU:l6gmwiTKsz0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?d=l6gmwiTKsz0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=nY_HksDtBJ4:023SjOa34uU:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?i=nY_HksDtBJ4:023SjOa34uU:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=nY_HksDtBJ4:023SjOa34uU:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=nY_HksDtBJ4:023SjOa34uU:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=nY_HksDtBJ4:023SjOa34uU:KwTdNBX3Jqk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?i=nY_HksDtBJ4:023SjOa34uU:KwTdNBX3Jqk" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/LoveTheDot/~4/nY_HksDtBJ4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.lovethedot.net/feeds/6098298383639177056/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7622136255348663693&amp;postID=6098298383639177056" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7622136255348663693/posts/default/6098298383639177056?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7622136255348663693/posts/default/6098298383639177056?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/LoveTheDot/~3/nY_HksDtBJ4/two-years-without-television-windows.html" title="Two Years Without Television – Windows Media Center and Streaming Alternatives to Cable" /><author><name>Paul Jackson</name><uri>http://www.blogger.com/profile/07495739164094993738</uri><email>pjackson@lovethedot.net</email><gd:extendedProperty name="OpenSocialUserId" value="17986907884361024776" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.lovethedot.net/2009/04/two-years-without-television-windows.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkcHQXk-fCp7ImA9WxVaEEk.&quot;"><id>tag:blogger.com,1999:blog-7622136255348663693.post-8739517761153696560</id><published>2009-04-06T09:14:00.001-07:00</published><updated>2009-04-06T11:53:50.754-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-06T11:53:50.754-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="software development" /><title>The Programmer Responsible for the World’s Financial Collapse</title><content type="html">&lt;p&gt;I knew it.&amp;#160; You knew it.&amp;#160; We just didn’t want to admit it.&amp;#160; There had to be &lt;em&gt;software&lt;/em&gt; at the heart of the world’s financial woes and &lt;em&gt;some&lt;/em&gt; way to blame a programmer.&amp;#160; &lt;/p&gt;  &lt;p&gt;Sure enough, the press has tracked down one of the programmers responsible for writing the software that helped financial companies with “&lt;a href="http://en.wikipedia.org/wiki/Securitization" target="_blank"&gt;securitisation&lt;/a&gt;”, or the turning of regular mortgage notes into derivative securities that no one actually understands.&lt;/p&gt;  &lt;p&gt;Michael Osinski, 55, retired from programming and now farming premium oysters off Long Island, was one of the programmers for a company that supplied this software to many financial firms and was involved in the new “feature” that added subprime mortgage market to the process.&amp;#160; &lt;/p&gt;  &lt;p&gt;Osinski decided to go public after being called a “devil” and “facilitator” by people who found out what he used to do.&amp;#160; &lt;/p&gt;  &lt;p&gt;Now, if I’d written that software I don’t think I’d go public … there’d probably be a gap on my resume, even, but Osinski decided to talk to the press, and he makes a really valid point:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&amp;quot;Securitisation is a good thing when it allows firms correctly to price risk into their calculations,&amp;quot; he said. &amp;quot;If people are re-paying their mortgages, then the process works fine. But if you put garbage in, you'll get junk out.&amp;quot; &lt;/p&gt; &lt;/blockquote&gt;  &lt;div style="float: right"&gt;&lt;img style="visibility: hidden; width: 0px; height: 0px" height="0" src="http://counters.gigya.com/wildfire/IMP/CXNID=2000002.0NXC/bT*xJmx*PTEyMzkwMzM2OTc1NDYmcHQ9MTIzOTAzMzcwNTUyMSZwPTg*MjEmZD*mZz*xJnQ9Jm89YzAwZGY3NjExZmQzNDExMWE1YzA4NGY1MTlkZTQzM2E=.gif" width="0" border="0" /&gt; &lt;object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="300" height="235" align="middle"&gt;                     &lt;param name="allowScriptAccess" value="sameDomain" /&gt;                     &lt;param name="movie" value="http://www.buzzdash.com/bb.swf?BB_id=158820" /&gt;                     &lt;param name="quality" value="high" /&gt;                     &lt;param name="wmode" value="transparent" /&gt;                     &lt;embed src="http://www.buzzdash.com/bb.swf?BB_id=158820" quality="high" wmode="transparent" width="300" height="235" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" /&gt;                     &lt;noembed&gt;&lt;a href="http://www.buzzdash.com/polls/should-developers-consider-the-larger-impact-of-their-work-158820/"&gt;Should developers consider the larger impact of their work?&lt;/a&gt; | &lt;a href="http://www.buzzdash.com"&gt;BuzzDash polls&lt;/a&gt;&lt;/noembed&gt;                 &lt;/object&gt;&lt;/div&gt;  &lt;p&gt;The good or bad of the software depends on how it’s used, the program itself is just a tool.&amp;#160; Like eBay, which is a great auction site, but has had prevalent fraud – is that the fault of the software or the users?&lt;/p&gt;  &lt;p&gt;But do we, as developers, have any responsibility to think about how the software we’re writing could be &lt;em&gt;misused&lt;/em&gt; and what the consequences might be?&amp;#160; &lt;/p&gt;  &lt;p&gt;We do have a responsibility to think about how it might be attacked by someone malicious, right?&amp;#160; The security of a system is our responsibility and we’re supposed to analyze the possible attack surfaces and methods to ensure that the system can’t be misused by an attacker – but what about misuse by a legitimate user?&lt;/p&gt;  &lt;p&gt;When dealing with security, I always tell my team to assume the client (whether the end-user or another development team) is either stupid or malicious.&amp;#160; Meaning that they will, at some point, send the most damaging input possible, either because they’re deliberately trying to break the system or they don’t know what they’re doing – and so the system must be protected from that.&lt;/p&gt;  &lt;p&gt;So does that extend to analyzing the possible negative impact of a new “feature” or system outside of the software itself?&amp;#160; Do we have a responsibility to ask: What will &lt;em&gt;using this software as designed &lt;/em&gt;do to the user, company or world?&lt;/p&gt;  &lt;p&gt;Or, even if we don’t have the responsibility, should we do it anyway because, sure-as-shootin’, somebody’ll say it’s our fault?&lt;/p&gt;  &lt;p&gt;&lt;a title="http://www.telegraph.co.uk/finance/financetopics/financialcrisis/5106510/Former-Wall-Street-computer-whizz-Michael-Osinski-admits-his-work-broke-the-banks.html" href="http://www.telegraph.co.uk/finance/financetopics/financialcrisis/5106510/Former-Wall-Street-computer-whizz-Michael-Osinski-admits-his-work-broke-the-banks.html"&gt;http://www.telegraph.co.uk/finance/financetopics/financialcrisis/5106510/Former-Wall-Street-computer-whizz-Michael-Osinski-admits-his-work-broke-the-banks.html&lt;/a&gt;&lt;/p&gt;  &lt;div&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fwww.lovethedot.net%2f2009%2f04%2fprogrammer-responsible-for-worlds.html"&gt;&lt;img alt="kick it on DotNetKicks.com" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.lovethedot.net%2f2009%2f04%2fprogrammer-responsible-for-worlds.html" border="0" /&gt;&lt;/a&gt; &lt;a href="http://dotnetshoutout.com/Love-the-Dot-The-Programmer-Responsible-for-the-Worlds-Financial-Collapse" rev="vote-for"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" alt="Shout it" src="http://dotnetshoutout.com/image.axd?url=http%3A%2F%2Fwww.lovethedot.net%2F2009%2F04%2Fprogrammer-responsible-for-worlds.html" /&gt;&lt;/a&gt;&lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7622136255348663693-8739517761153696560?l=www.lovethedot.net' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/YSlKq1-oosU9O5kvI5c0ozzQz74/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/YSlKq1-oosU9O5kvI5c0ozzQz74/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/YSlKq1-oosU9O5kvI5c0ozzQz74/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/YSlKq1-oosU9O5kvI5c0ozzQz74/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=EYDK5ZNiJEA:vUtwGCL751o:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=EYDK5ZNiJEA:vUtwGCL751o:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=EYDK5ZNiJEA:vUtwGCL751o:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?i=EYDK5ZNiJEA:vUtwGCL751o:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=EYDK5ZNiJEA:vUtwGCL751o:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?i=EYDK5ZNiJEA:vUtwGCL751o:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=EYDK5ZNiJEA:vUtwGCL751o:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?i=EYDK5ZNiJEA:vUtwGCL751o:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=EYDK5ZNiJEA:vUtwGCL751o:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=EYDK5ZNiJEA:vUtwGCL751o:l6gmwiTKsz0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?d=l6gmwiTKsz0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=EYDK5ZNiJEA:vUtwGCL751o:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?i=EYDK5ZNiJEA:vUtwGCL751o:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=EYDK5ZNiJEA:vUtwGCL751o:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=EYDK5ZNiJEA:vUtwGCL751o:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/LoveTheDot?a=EYDK5ZNiJEA:vUtwGCL751o:KwTdNBX3Jqk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/LoveTheDot?i=EYDK5ZNiJEA:vUtwGCL751o:KwTdNBX3Jqk" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/LoveTheDot/~4/EYDK5ZNiJEA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.lovethedot.net/feeds/8739517761153696560/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7622136255348663693&amp;postID=8739517761153696560" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7622136255348663693/posts/default/8739517761153696560?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7622136255348663693/posts/default/8739517761153696560?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/LoveTheDot/~3/EYDK5ZNiJEA/programmer-responsible-for-worlds.html" title="The Programmer Responsible for the World’s Financial Collapse" /><author><name>Paul Jackson</name><uri>http://www.blogger.com/profile/07495739164094993738</uri><email>pjackson@lovethedot.net</email><gd:extendedProperty name="OpenSocialUserId" value="17986907884361024776" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.lovethedot.net/2009/04/programmer-responsible-for-worlds.html</feedburner:origLink></entry></feed>
