Загрузка данных
using System.Diagnostics;
namespace ConsoleApp5
{
internal class Program
{
static async Task Main(string[] args)
{
/*var thread = new Thread(() =>
{
Console.WriteLine("Thread started");
Thread.Sleep(1000);
})
{
IsBackground = true,
Name = "Worker",
Priority = ThreadPriority.BelowNormal,
};
thread.Start();
thread.Join();*/
/*int result = await Task.Run(()=>
{
return Enumerable.Range(1, 1_000_000).Sum(x => x % 7);
});
Console.WriteLine(result);*/
const int limit = 5_000_000;
Console.CursorVisible = false;
Console.WriteLine("Counting prime numbers");
Console.WriteLine("1 - in main thread");
Console.WriteLine("2 - in Tast.Run()");
var choice = Console.ReadKey(intercept: true).KeyChar;
if(choice == '1')
{
}
else if (choice == '2')
{
}
Console.CursorVisible = true;
static void RunBlocking(int limit)
{
Console.WriteLine("Counting...");
var sw = Stopwatch.StartNew();
int count = PrimeCounter.Count(limit, progress: null, CancellationToken.None);
Console.WriteLine($"Found {count} prime numbers in {sw.Elapsed.TotalSeconds} seconds");
}
static async Task RunWithTaskRun(int limit)
{
using var cts = new CancellationTokenSource();
var progress = new ProgressState();
var sw = Stopwatch.StartNew();
Task<int> work = Task.Run(() => PrimeCounter.Count(limit, progress: null, CancellationToken.None));
char[] spinner = ['|', '/', '-', '\\'];
int frame = 0;
while(!work.IsCompleted)
{
if(Console.KeyAvailable&&Console.ReadKey(intercept: true).Key == ConsoleKey.Escape)
{
cts.Cancel();
}
Console.Write($"\r{spinner[frame++ % spinner.Length]}" +
$"{progress.Percent,3}% {sw.Elapsed:mm\\:ss\\.f} " +
$"(Esc - cancel)");
await Task.WhenAny(work, Task.Delay(100));
}
Console.WriteLine();
try
{
int count = await work;
Console.WriteLine($"{count} prinme numbers found");
}
catch (OperationCanceledException)
{
Console.WriteLine($"Operation cancelled by user");
}
}
}
static class PrimeCounter
{
public static int Count(int limit, ProgressState? progress, CancellationToken token)
{
int count = 0;
const int step = 50_000;
for(int n = 2; n <= limit; n++)
{
if(IsPrime(n))
{
count++;
}
if(n % step == 0)
{
token.ThrowIfCancellationRequested();
progress?.Report((int)100L * n/limit);
}
}
progress?.Report(100);
return count;
}
private static bool IsPrime(int n)
{
if (n < 4) return n > 1;
if (n % 2 == 0) return false;
for (int d = 3; d * d <= n; d += 2)
{
if (n % d == 0) return false;
}
return true;
}
}
public sealed class ProgressState
{
private int _percent;
public int Percent => Volatile.Read(ref _percent);
public void Report(int value) => Volatile.Write(ref _percent, value);
}
}
}