c# - Restart concurrent tasks as soon as they fail for x number of times -
i have console app making http queries , adding/updating products in database according response. fail , need retried few times.
the way came use dictionary store product id , task. can check task results , re-run.
this working strikes me inefficient. tasks not being re-created until tasks have finished. more efficient if restarted can't figure out how this. every retry involves query database id stored.
i made small app shows how retrying failed requests.
can suggest more efficient method retrying?
class program { private static void main(string[] args) { httpquery m = new httpquery(); var task = task.run(() => m.start()); task.waitall(task); console.writeline("finished"); console.readline(); } } class httpquery { public async task start() { // dictionary key represent reference needs processed , bool whether has completed or not concurrentdictionary<int, task<bool>> monitor = new concurrentdictionary<int, task<bool>>(); // start async tasks. console.writeline("starting first try"); (int = 0; < 1000; i++) { console.write(i+","); monitor[i] = this.query(i); } // wait completion await task.whenall(monitor.values.toarray()); console.writeline(); // start retries // number of retries per query int retries = 10; int count = 0; // check if max retries exceeded or completed while (count < retries && monitor.any(x => x.value.result == false)) { // make list of numbers failed list<int> retrylist = monitor.where(x => x.value.result == false).select(x => x.key).tolist(); console.writeline("starting try number: " + (count+1) + ", processing: " + retrylist.count); // create list of tasks wait list<task<bool>> towait = new list<task<bool>>(); foreach (var in retrylist) { console.write(i + ","); monitor[i] = this.query(i); towait.add(monitor[i]); } // wait completion await task.whenall(towait.toarray()); console.writeline(); count++; } console.writeline("ended"); console.readline(); } public async task<bool> query(int i) { // simulate http request may or may not fail random r = new random(); int delay = * r.next(1, 10); await task.delay(delay); if (r.next(0,2) == 1) { return true; } else { return false; } } }
you can create method , wrap these ugly retry logic. of ugly code goes away :)
public async task start() { const int maxnumberoftries = 10; list<task<bool>> tasks = new list<task<bool>>(); (int = 0; < 1000; i++) { tasks.add(this.querywithretry(i, maxnumberoftries)); } await task.whenall(tasks); } public async task<bool> querywithretry(int i, int numoftries) { int tries = 0; bool result; { result = await query(i); tries++; } while (!result && tries < numoftries); return result; }
Comments
Post a Comment