title: How to retry until some condition is met
body: <p>I need to retry a certain method until it returns a non-empty Guid. </p>
  
  <p>There's an awesome <a href="https://stackoverflow.com/a/1563234">answer</a> that retries based on whether there is an exception; however, I would like to generalize this class to be able to handle any specified condition. </p>
  
  <p>The current usage will perform an action a specific number of times until there are no exceptions:</p>
  
  <pre><code>Retry.Do(() =&gt; SomeFunctionThatCanFail(), TimeSpan.FromSeconds(1));
  </code></pre>
  
  <p>or:</p>
  
  <pre><code>Retry.Do(SomeFunctionThatCanFail, TimeSpan.FromSeconds(1));
  </code></pre>
  
  <p>or:</p>
  
  <pre><code>int result = Retry.Do(SomeFunctionWhichReturnsInt, TimeSpan.FromSeconds(1), 4);
  </code></pre>
  
  <p>How can I modify this class such that it retries based on the return value of the function that I pass in?</p>
  
  <p>For example, If I wanted to retry until my function returned 3:</p>
  
  <pre><code>Retry.Do(() =&gt; SomeFunctionThatCanFail(), TimeSpan.FromSeconds(1)).Until(3);
  </code></pre>
  
  <p>Which would mean execute SomeFunctionThatCanFail(), every 1 second, until SomeFunctionThatCanFail() = 3?</p>
  
  <p><strong>How would I generalize the usage of Retry.Do until a condition is met?</strong></p>
  
  <pre><code>public static class Retry
  {
     public static void Do(
         Action action,
         TimeSpan retryInterval,
         int retryCount = 3)
     {
         Do&lt;object&gt;(() =&gt; 
         {
             action();
             return null;
         }, retryInterval, retryCount);
     }
  
     public static T Do&lt;T&gt;(
         Func&lt;T&gt; action, 
         TimeSpan retryInterval,
         int retryCount = 3)
     {
         var exceptions = new List&lt;Exception&gt;();
  
         for (int retry = 0; retry &lt; retryCount; retry++) //I would like to change this logic so that it will retry not based on whether there is an exception but based on the return value of Action
         {
            try
            { 
                if (retry &gt; 0)
                    Thread.Sleep(retryInterval);
                return action();
            }
            catch (Exception ex)
            { 
                exceptions.Add(ex);
            }
         }
  
         throw new AggregateException(exceptions);
     }
  }
  </code></pre>