title: Why does Task.Delay() allow an infinite delay?
body: <p>After my application froze I tracked down the cause to a thread waiting on a task created by <code>Task.Delay()</code> (or <code>TaskEx.Delay()</code> in .NET 4.0) for which it provided a computed <code>TimeSpan</code> that, due to a bug, was on occasion computed to a <code>TimeSpan</code> with a <code>TotalMilliseconds</code> of less than or equal to <code>-1</code> and greater than <code>-2</code> (i.e. anywhere between -10000 to -19999 ticks, inclusive).</p>
  
  <p>It appears that when you pass a negative <code>TimeSpan</code> that is <code>-2</code> milliseconds or lower, the method correctly throws an <code>ArgumentOutOfRangeException</code>, but when you provide a negative TimeSpan from the range described above, it returns a <code>Task</code> that never completes (by setting the underlying <code>System.Threading.Timer</code> to a <code>dueTime</code> of -1 which denotes infinity). That means that any continuations set on that task will never execute, and any poor thread that happens to <code>.Wait()</code> on that <code>Task</code> will forever be blocked.</p>
  
  <p>What possible use can a <code>Task</code> that never completes have? Would anyone expect such a return value? Shouldn't any negative value passed to <code>.Delay()</code>, including values in that special range, throw an <code>ArgumentOutOfRangeException</code>?</p>