c# - Async Await to Keep Event Firing -


i have question async\await in c# .net app. i'm trying solve problem in kinect based application me illustrate, i've crafted analogous example:

imagine have timer, called timer1 has timer1_tick event set up. now, action take on event update ui current date time.

 private void timer1_tick(object sender, eventargs e)     {         txttimervalue.text = datetime.now.tostring("hh:mm:ss.fff", cultureinfo.invariantculture);     } 

this simple enough, ui updates every few hundredths of seconds , can happily watch time go by.

now imagine want calculate first 500 prime numbers in same method so:

 private void timer1_tick(object sender, eventargs e)     {         txttimervalue.text = datetime.now.tostring("hh:mm:ss.fff", cultureinfo.invariantculture);         list<int> primenumberslist = workoutfirstnprimenumbers(500);         printprimenumberstoscreen(primenumberslist);     }      private list<int> workoutfirstnprimenumbers(int n)     {         list<int> primenumberslist = new list<int>();         txtprimeanswers.clear();         int counter = 1;         while (primenumberslist.count < n)         {             if (determineifprime(counter))             {                 primenumberslist.add(counter);              }             counter++;         }          return primenumberslist;     }      private bool determineifprime(int n)     {         (int = 2; < n; i++)         {             if (n % == 0)             {                 return false;             }         }         return true;     }     private void printprimenumberstoscreen(list<int> primenumberslist)     {         foreach (int primenumber in primenumberslist)         {             txtprimeanswers.text += string.format("the value {0} prime \r\n", primenumber);         }     } 

this when experience problem. intensive method calculates prime numbers blocks event handler being run - hence timer text box updates every 30 seconds or so.

my question is, how can resolve while observing following rules:

  • i need ui timer textbox smooth before, pushing intensive prime number calculation different thread. guess, enable event handler run before because blocking statement no longer there.
  • each time prime number calculation function finishes, it's result written screen (using printprimenumberstoscreen() function) , should started again, in case prime numbers change of course.

i have tried things async/await , making prime number calculation function return task> haven't managed resolve problem. await call in timer1_tick event still seems block, preventing further execution of handler.

any gladly appreciated - i'm @ accepting correct answers :)

update: grateful @sstan able provide neat solution problem. however, i'm having trouble applying real kinect-based situation. little concerned making question specific, have posted follow new question here: kinect frame arrived asynchronous

so want start task without waiting result. when task has finished calculating should update ui.

first things async-await, later answer

the reason ui isn't responsive during long action because didn't declare event handler async. easiest way see result of creating event handler button:

synchronous - ui blocked during execution:

private void button1_clicked(object sender, eventargs e) {     list<int> primenumberslist = workoutfirstnprimenumbers(500);     printprimenumberstoscreen(primenumberslist); } 

asynchronous - ui responsive during execution:

private async void button1_clicked(object sender, eventargs e) {     list<int> primenumberslist = await task.run( () => workoutfirstnprimenumbers(500));     printprimenumberstoscreen(primenumberslist); } 

note differences:

  • the function declared async
  • instead of calling function, task started using task.run
  • the await statement makes sure ui-thread returns , keeps handling ui requests.
  • once task finished, ui thread continues next part of await.
  • the value of await return of workoutfirstnprimenumber function

note:

  • normally you'll see async functions return task instead of void , task<tresult> instead of tresult.
  • the await task void , await task<tresult> tresult.
  • to start function separate task use task.run ( () => myfunction(...))
  • the return of task.run awaitable task.
  • whenever want use await, you'll have declare function async, , return task or task<tresult>.
  • so callers have async , forth.
  • the async function may return void event handler.

your problem: timer tick reported when calculations still busy

the problem timer faster calculations. want if new tick reported when previous calculations not finished

  1. start new calculations anyhow. might lead lot of threads doing calculations @ same time.
  2. ignore tick until no calculations busy
  3. you choose let 1 task calculations , start them finished. in case calculations run continuously

(1) start task, not await it.

private void button1_clicked(object sender, eventargs e) {     task.run ( () =>     {    list<int> primenumberslist = workoutfirstnprimenumbers(500);         printprimenumberstoscreen(primenumberslist);     });  } 

(2) ignore tick if task still busy:

task primecalculationtask = null; private void button1_clicked(object sender, eventargs e) {     if (primecalculationtask == null || primecalculationtask.iscompleted)     {   // previous task finished. stat new 1         task.run ( () =>         {    list<int> primenumberslist = workoutfirstnprimenumbers(500);             printprimenumberstoscreen(primenumberslist);         });      } } 

(3) start task calculates continuously

private void starttask(cancellationtoken token) {     task.run( () =>     {         while (!token.iscancelrequested)         {             list<int> primenumberslist = workoutfirstnprimenumbers(500);             printprimenumberstoscreen(primenumberslist);         }      })  } 

Comments

Popular posts from this blog

php - Admin SDK -- get information about the group -

dns - How To Use Custom Nameserver On Free Cloudflare? -

Python Error - TypeError: input expected at most 1 arguments, got 3 -