c# - Are there better ways for updating an execution timer every second than using a background worker that checks every 150 ms? -


to show timer how long specific process runs i'm using background worker update execution time label. naturally should done every second user sees increases consistently.

after trying around bit , failing utterly went down road i'm checking every 150 milliseconds if next second there , update display.

    private void executiontimerbackgroundworker_dowork(object sender, doworkeventargs e)     {         stopwatch executiontime = new stopwatch();         double lastupdateatseconds = 0;          executiontime.start();          while (!executiontimerbackgroundworker.cancellationpending)         {             thread.sleep(150);  // sleep while give other threads time stuff              if (executiontime.elapsed.totalseconds > lastupdateatseconds + 1)   // update execution time display once per second             {                 executiontimerbackgroundworker.reportprogress(0, executiontime.elapsed);    // update execution time display                 lastupdateatseconds  = executiontime.elapsed.totalseconds;             }         }          executiontime.stop();     }      private void executiontimerbackgroundworker_progresschanged(object sender, progresschangedeventargs e)     {         // update display execution time in minutes:seconds format         executiontimelabel.text = ((timespan) e.userstate).tostring(@"mm\:ss");         } 

now seems me bit inefficient run every 150 milliseconds "hey has next second arrived or not". tried different approach calculate how time needed until next second @ 1 had few instances jump 2 instead of 1 second each in display happened.

so question here is: there more efficient way this? or how should done?

i have found if want display changes every second should attempt make changes every tenth of second appear continuous user - maybe more that.

now avoid use of background worker entirely this. instead i'd use microsoft's reactive framework (nuget "rx-main" or "rx-winforms" in case).

here's basic code that:

var start = datetimeoffset.now; var subscription =     observable         .interval(timespan.fromseconds(0.1))         .select(x => datetimeoffset.now.subtract(start).totalseconds)         .select(x => (int)x)         .distinctuntilchanged()         .observeon(this)         .subscribe(x => this.label1.text = x.tostring()); 

this code creates timer (.interval(...)) fires every tenth of second. computes time in seconds since code started, turns integer, , drops consecutive values same. observes observable on ui thread (.observeon(this)) , subscribes assigning value (in case) label on form - use whatever control type liked.

to stop subscription, this:

subscription.dispose(); 

it clean properly.

the code should quite readable event if not familiar reactive framework.

now i've used datetimeoffset instead of stopwatch don't need high resolution timing updates occurring every second. nothing stop using stopwatch if wanted.


Comments

Popular posts from this blog

angularjs - ADAL JS Angular- WebAPI add a new role claim to the token -

php - CakePHP HttpSockets send array of paramms -

node.js - Using Node without global install -