title: Parallel I/O and Retry Logic for Error Handling
body: <p>Normally parallel processing is relevant only to CPU intensive operations.  However, PLINQ specifically provides IO-intensive support using the WithDegreeOfParallelism extension.  For example:</p>
  
  <pre><code>from site in new[]
  {
      "www.albahari.com",
      "www.linqpad.net",
      "www.oreilly.com",
      "www.takeonit.com",
      "stackoverflow.com",
      "www.rebeccarey.com"  
  }
  .AsParallel().WithDegreeOfParallelism(6)
  let p = new Ping().Send (site)
  select new
  {
      site,
      Result = p.Status,
      Time = p.RoundtripTime
  }
  </code></pre>
  
  <p>But if <a href="http://www.albahari.com/threading/part5.aspx#_Calling_Blocking_Functions_PLINQ" rel="nofollow">supporting IO is the goal of WithDegreeOfParallelism</a>, how then can PLINQ be further extended or used to achieve a "retry" effect, which is typical of IO operations?  And what about a "delay" effect? </p>
  
  <p>For example, if IO through a WCF service call throws a CommunicationException, I might want the same request made again with a "3 tries" strategy before moving on to the next resource.  I might also want a minute wait between each try.  And while I "wait" for a minute between each try, I don't want a thread blocked waiting.</p>
  
  <p>In this <a href="http://blogs.msdn.com/b/pfxteam/archive/2009/08/04/9857477.aspx" rel="nofollow">MSDN article</a> the author starts with a query similar to what I've shown above.  He then transforms the query so that no threads are blocking.  Unfortunately he lost the WithDegreeOfParallelism in the process.  And either way, he did not address the issue of "retries" when an error occurs.</p>
  
  <p>Anyone have or know of a slick way of doing this?  </p>
  
  <p>I was thinking of making a special IEnumerable wrapper that permitted values to be "re-inserted" while the collection was being walked by PLINQ.  This would indeed cause a "retry" behavior, but it would still not allow for the "1 minute delay between retries" requirement.  I could create the 1 minute delay with Thread.Sleep(), but I'm trying not to block threads.</p>
  
  <p>Thoughts?</p>