I commonly employ a while loop that continues to try some operation until either the operation succeeds or a timeout has elapsed:
bool success = false int elapsed = 0 while( ( !success ) && ( elapsed < 10000 ) ) { Thread.sleep( 1000 ); elapsed += 1000; success = ... some operation ... }
I know there a couple of way to implement this, but the basic point is that I repeatedly try some operation with a sleep until success or I've slept too long in aggregate.
Is there a built-in .net class/method/etc to save me from re-writing this pattern all over the place? Perhaps input is an Func(of bool) and the timeout?
Edit
Thanks to all who contributed. I opted for the sleep() approach because it was the least complicated and I'm totally anti-complexity =) Here's my (still needs to be tested) implimentation:
public static bool RetryUntilSuccessOrTimeout( Func<bool> task , TimeSpan timeout , TimeSpan pause ) { if ( pause.TotalMilliseconds < 0 ) { throw new ArgumentException( "pause must be >= 0 milliseconds" ); } var stopwatch = Stopwatch.StartNew(); do { if ( task() ) { return true; } Thread.Sleep( ( int )pause.TotalMilliseconds ); } while ( stopwatch.Elapsed < timeout ); return false; }
sleep(1) at the beginning or end of the loop body).
Python provides two keywords that terminate a loop iteration prematurely: The Python break statement immediately terminates a loop entirely. Program execution proceeds to the first statement following the loop body. The Python continue statement immediately terminates the current loop iteration.
You could use SpinWait.SpinUntil
See https://msdn.microsoft.com/en-us/library/dd449238(v=vs.110).aspx
bool spinUntil = System.Threading.SpinWait.SpinUntil(() => job.IsDisposed, TimeSpan.FromSeconds(5));
You could wrap your algorithm in a method:
public bool RetryUntilSuccessOrTimeout(Func<bool> task, TimeSpan timeSpan) { bool success = false; int elapsed = 0; while ((!success) && (elapsed < timeSpan.TotalMilliseconds)) { Thread.Sleep(1000); elapsed += 1000; success = task(); } return success; }
and then:
if (RetryUntilSuccessOrTimeout(() => SomeTask(arg1, arg2), TimeSpan.FromSeconds(10))) { // the task succeeded }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With