static Task<int> GetPrimeCountAsync(int start, int stop)
is for counting the number of primes in a closed interval[start,stop]
where2 < start <= stop
.static void WrapperAsync()
is for printing a list of 10 executions ofGetPrimeCountAsync
, each with a closed interval spanning fromi == 0 ? 3 : 1000_000 * i
to1000_000 * (i + 1) - 1
, wherei
spinning from0
to9
. Inside this method, there are 3 cases, only one is activated.
Questions
If we compare case 1, 2 and 3, there are the same glitches in case 1 and 2 but not in case 3. The case 3 is the wanted result.
Actually the glitches can be removed by buffering the loop counter with local variables as follows:
int start = i == 0 ? 3 : 1000_000 * i;
int stop = 1000_000 * (i + 1) - 1;
And then just pass start
and stop
to GetPrimeCountAsync
and WriteLine
.
The question is: What causes these 2 glitches in case 1 and 2?
Complete Code
using System;
using System.Linq;
using System.Threading.Tasks;
using static System.Console;
class Program
{
static void Main()
{
WrapperAsync();
WriteLine("Ended...");
}
static void WrapperAsync()
{
for (int i = 0; i < 10; i++)
{
//int start = i == 0 ? 3 : 1000_000 * i;
//int stop = 1000_000 * (i + 1) - 1;
// case 1: OnCompleted
var awaiter = GetPrimeCountAsync(i == 0 ? 3 : 1000_000 * i, 1000_000 * (i + 1) - 1).GetAwaiter();
awaiter.OnCompleted(() => WriteLine($"The number of primes between {(i == 0 ? 3 : 1000_000 * i)} and {1000_000 * (i + 1) - 1} is {awaiter.GetResult()}"));
// case 2: ContinueWith
//var task = GetPrimeCountAsync(i == 0 ? 3 : 1000_000 * i, (i + 1) * 1000_000 - 1);
//task.ContinueWith(t => WriteLine($"The number of primes between {(i == 0 ? 3 : 1000_000 * i)} and {(i + 1) * 1000_000 - 1} is {t.GetAwaiter().GetResult()}"));
// case 3: without OnCompleted and without ContinueWith
//var task = GetPrimeCountAsync(i == 0 ? 3 : 1000_000 * i, (i + 1) * 1000_000 - 1);
//WriteLine($"The number of primes between {(i == 0 ? 3 : 1000_000 * i)} and {(i + 1) * 1000_000 - 1} is {task.GetAwaiter().GetResult()}");
}
}
// Note that 2 < start <= stop
static Task<int> GetPrimeCountAsync(int start, int stop)
{
var count = ParallelEnumerable.Range(start, stop - start + 1)
.Where(i => i % 2 > 0)
.Count(j => Enumerable.Range(3, (int)Math.Sqrt(j) - 1).Where(k => k % 2 > 0).All(l => j % l > 0));
return Task.Run(() => count);
}
}