protected Timer ProcessRetriesUsingTimer(Func <bool> attempter, Action <OperationResultEventArgs> callback) { int tryCount = 0; Timer timer = null; TimerCallback timerCallback = (state) => { try { OperationResultEventArgs resultArgs = null; try { resultArgs = TryOnce(attempter, ++tryCount, timer); } catch (Exception ex) { resultArgs = new OperationResultEventArgs(ResultEnum.Failure, ex, tryCount); } if (resultArgs != null && callback != null) { callback(resultArgs); } } // Supressing all exceptions to avoid an unhandled exception from killing the entire windows process catch { } }; // Creating a single-time and immediate timer for the first attempt timer = new Timer(timerCallback, null, 0, 0); return(timer); }
protected BackgroundWorker CreateBackgroundRetryWorker(Func <bool> attempter, Action <OperationResultEventArgs> callback) { var worker = new BackgroundWorker(); bool success = false; int tryCount = 0; Exception error = null; // Creating the handler delegate, which creates another delegate itself worker.DoWork += delegate(object sender, DoWorkEventArgs e) { Func <bool> callWrapper = delegate { if (worker.CancellationPending) { e.Cancel = true; // Indicate that cancellation occured (no exception) return(true); // Returning without an exception will end the retry cycle } return(attempter()); }; success = TryAll(callWrapper, out tryCount, out error); }; if (callback != null) { worker.RunWorkerCompleted += delegate(object sender, RunWorkerCompletedEventArgs args) { var result = args.Error != null ? ResultEnum.Failure : args.Cancelled ? ResultEnum.Canceled : ResultEnum.Success; var resultArgs = new OperationResultEventArgs(result, args.Error ?? error, tryCount); callback(resultArgs); }; } return(worker); }
protected abstract void NotifyAsyncCallback(OperationResultEventArgs args);