andrew4582

RetryOnFault

Dec 22nd, 2010
244
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 3.00 KB | None | 0 0
  1.         /// <summary>
  2.         /// Retries the specified function a certin amount of times before throwing the exception
  3.         /// </summary>
  4.         /// <typeparam name="T">Result of the sucessfull function</typeparam>
  5.         /// <param name="function">Function to excecute</param>
  6.         /// <param name="maxTries">The maximum amount of attempts to exceute the function</param>
  7.         /// <param name="timeoutMilliseconds">Timeout to wait for a function to finish execution</param>
  8.         /// <returns></returns>
  9.         public static T RetryOnFault<T>(Func<T> function,int maxTries,int timeoutMilliseconds = 0) {
  10.  
  11.             if(function == null)
  12.                 throw new ArgumentNullException("function");
  13.  
  14.             if(Math.Max(maxTries,0) == 0)
  15.                 throw new ArgumentOutOfRangeException("maxTries");
  16.  
  17.             for(int i = 0;i < maxTries;i++) {
  18.                 bool timedout = false;
  19.                 Exception error = null;
  20.                 T result = default(T);
  21.  
  22. #if Net4
  23.                 //start a new task
  24.                 var t = Task.Factory
  25.                     .StartNew<T>(function);
  26.  
  27.                 //for debugging
  28.                 t.ContinueWith((finnished) => Debug.WriteLine("Task: " + t.Id + " result: " + finnished.Result));
  29.  
  30.                 //wait on the task for the specified time
  31.                 if(timeoutMilliseconds > 0)
  32.                     timedout = !t.Wait(timeoutMilliseconds);
  33.  
  34.                 if(t.IsFaulted)
  35.                     error = t.Exception ?? new Exception("Unknown error");
  36.                 else
  37.                     result = t.Result;
  38. #else
  39.                 AutoResetEvent waitEvent = new AutoResetEvent(false);
  40.  
  41.                 //queue up a worker thread
  42.                 ThreadPool.QueueUserWorkItem((state) => {
  43.                     try {
  44.                         result = ((Func<T>)state)();
  45.                     }
  46.                     catch(Exception ferror) {
  47.                         error = ferror;
  48.                     }
  49.                     finally {
  50.                         //resume back
  51.                         if(!waitEvent.SafeWaitHandle.IsClosed)
  52.                             waitEvent.Set();
  53.                     }
  54.                 },function);
  55.  
  56.                 //wait on the task for the specified time
  57.                 timedout = !waitEvent.WaitOne(timeoutMilliseconds);
  58.                 waitEvent.Close();
  59.                 Debug.Write("Result: " + result);
  60. #endif
  61.                 //check if task faulted or timed out
  62.                 if(error != null || timedout) {
  63.                     if(timedout)
  64.                         error = new TimeoutException();
  65.  
  66.                     Debug.WriteLine("Attempt " + (i + 1) + " failed: " + error.Message);
  67.  
  68.                     //check how many errors
  69.                     if(i == maxTries - 1)
  70.                         throw error;
  71.                 }
  72.                 else
  73.                     return result;
  74.             }
  75.  
  76.             //should never get here
  77.             return default(T);
  78.         }
Advertisement
Add Comment
Please, Sign In to add comment