c# - Technique to prevent accidental re-enumeration of IEnumerable? -


i spent time scratching head when breakpoint seemed magically appear twice in same spot, inside enumerator.

it turned out bug straight forward oversight:

    protected override void extract()     {         loggettingoffers();         var offerids = cakemarketingutility.offerids(advertiserid);         logextractingclicks(offerids);         foreach (var offerid in offerids)         {             int rowcount;             var clicks = retryutility.retry(3, 10000, new[] { typeof(exception) }, () =>             {                 return cakemarketingutility.enumerateclicks(daterange, advertiserid, offerid);             });             foreach (var clickbatch in clicks.inbatches(1000))             {                 logextractedclicks(offerid, clickbatch);                  // should clickbatch, not clicks                 add(clicks);             }         }         end();     } 

this leads me wonder (if any) kind of preventative measures 1 might take write code catches error this.

note, i'm not positive makes sense go down line of thought - maybe answer "don't write incorrect code", i'm willing accept..

here's actual code yields results:

    public static ienumerable<click> enumerateclicks(daterange daterange, int advertiserid, int offerid)     {         // initialize start @ first row         int startatrow = 1;          // hard code upper limit max number of rows returned in 1 call         int rowlimitforonecall = 5000;          bool done = false;         int total = 0;         while (!done)         {             logger.info("extracted total of {0} rows, checking more, starting @ row {1}..", total, startatrow);              // prepare request             var request = new clicksrequest             {                 start_date = daterange.fromdate.tostring("mm/dd/yyyy"),                 end_date = daterange.todate.tostring("mm/dd/yyyy"),                 advertiser_id = advertiserid,                 offer_id = offerid,                 row_limit = rowlimitforonecall,                 start_at_row = startatrow             };              // create client, call service , check response             var client = new clicksclient();             var response = client.clicks(request);             if (!response.success)             {                 throw new exception("clicksclient failed");             }              // update running total             total += response.rowcount;              // return result             foreach (var click in response.clicks)                 yield return click;              // update stopping condition loop             done = (response.rowcount < rowlimitforonecall);              // increment start row next iteration             startatrow += rowlimitforonecall;         }          logger.info("extracted total of {0}, done.", total);     } 

for specific issue, i'd solution "don't write incorrect code". when results can generated without altering state (like when enumerate elements list), think should okay create multiple enumerators enumerable.

you create ienumerable wrapper ensure getenumerator called once, if legitimately need call twice? want catch mistakes, not catch enumerables being enumerated multiple times, , that's not can put in software solution.

maybe issue clickbatch , clicks have same type, compiler couldn't distinguish between either.


Comments

Popular posts from this blog

php - Calling a template part from a post -

Firefox SVG shape not printing when it has stroke -

How to mention the localhost in android -