|
In this article we will explore TimeoutAfter and RetryonFault combinators while executing async task. Long running operation should not run forever, at some point of time timeout exception needs to be thrown. Long running operation might be tried for certain times for cetain intervals even if doesn't succed in certain interval of time, timout exception needs to be thrown.
Let's see how we can achieve.
Step 1: Place two buttons and two labels in the Form to explore TimeoutAfter and RetryonFault combinators.
Name the button as TimeoutAfter and RetryonFault.
Step 2: Add below long running operation method.
public async Task<int> LongRunningOperation() { return await TaskEx.RunEx<int>(async () => { Thread.Sleep(3500); return 123; }); }
TimeoutAfter
Step 3: Add TimeoutAfter method which will throw exception if it takes more than specified amount of delay.
public static async Task<T> TimeoutAfter<T>(Task<T> task, int delay) { await TaskEx.WhenAny(task, TaskEx.Delay(delay)); if (!task.IsCompleted) throw new TimeoutException("Timeout hit."); return await task; }
Step 4: Add click method to TimeoutAfter button. If LongRunningOperation operation takes more than 3 seconds TimeoutException will be thrown.
private async void TimeoutAfter_Click(object sender, EventArgs e) { try { int result = await TimeoutAfter(LongRunningOperation(), 3000); label1.Text = "Operation completed successfully. Result is " + result; } catch (TimeoutException) { label1.Text = "Timeout - operation took longer than 3 seconds."; } }
RetryonFault
Step 3: Add RetryonFault method to try certain times if the operation fails. If operation succeeds retry won't happen.
public static async Task<T> RetryOnFault<T>(Func<Task<T>> function, int maxTries) { for (int i = 0; i < maxTries; i++) { try { return await function(); } catch { if (i == maxTries - 1) throw; } } return default(T); }
Step 4: Add click method to RetryonFault button. If LongrunnintOperation operation could not completed in 3 second after three attempt Timeout exception will be thrown.
public static async Task<T> RetryOnFault<T>(Func<Task<T>> function, int maxTries) { for (int i = 0; i < maxTries; i++) { try { return await function(); } catch { if (i == maxTries - 1) throw; } } return default(T); }
This ends the article of using TimeoutAfter and RetryonFault combinators.
|