I have a question about async \ await in a C # .NET application. I'm actually trying to solve this problem in a Kinect based application, but to help me illustrate this, I created this similar example:
Imagine that we have a timer called timer 1 in which the Timer1_Tick event is set. Now, the only action I take on this event is updating the user interface with the current time.
private void Timer1_Tick(object sender, EventArgs e) { txtTimerValue.Text = DateTime.Now.ToString("hh:mm:ss.FFF", CultureInfo.InvariantCulture); }
It's simple enough, my user interface is updated every few hundredths of a second, and I can enjoy watching the time.
Now imagine that I also want to calculate the first 500 primes in the same method:
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) { for (int i = 2; i < n; i++) { if (n % i == 0) { return false; } } return true; } private void PrintPrimeNumbersToScreen(List<int> primeNumbersList) { foreach (int primeNumber in primeNumbersList) { txtPrimeAnswers.Text += String.Format("The value {0} is prime \r\n", primeNumber); } }
This is when I experience this problem. An intensive method that calculates prime numbers blocks the start of the event handler, so the timer text box is now updated only every 30 seconds.
My question is how can I solve this by following these rules:
- I need the UI timer text box to be as smooth as before, perhaps by pushing the computation of an intensive prime number to another stream. I think this will allow the event handler to work as often as before because the lock statement no longer exists.
- Every time a function for calculating primes ends, it should be written to the screen (using my PrintPrimeNumbersToScreen () function), and it should be started immediately again, just in case these primes change, of course.
I tried to do some things with async / await and force the function to calculate the number of primes to return the> task, but I was not able to solve my problem. Waiting for a call in the Timer1_Tick event is still blocked, which prevents further execution of the handler.
Any help would be appreciated - I accept the correct answers very well :)
Update: I am very grateful to @sstan, who was able to provide a neat solution to this problem. However, I am having problems applying this in my actual Kinect situation. Since I am a little worried about the question that this question is too specific, I posted the following question: Kinect Frame arrived asynchronously