Outils pour utilisateurs

Outils du site


developpement:dotnet:csharp:introduction

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentesRévision précédente
Prochaine révision
Révision précédente
Dernière révisionLes deux révisions suivantes
developpement:dotnet:csharp:introduction [2023/10/04 17:23] – [Task Parallel Library (TPL)] sgariepydeveloppement:dotnet:csharp:introduction [2023/10/05 15:11] – [PLINQ] sgariepy
Ligne 1271: Ligne 1271:
  
 Le cas en parallèle prend plus de temps dû au overhead.  L'instruction n'étant pas assez complexe pour justifier la parallèlisation. Le cas en parallèle prend plus de temps dû au overhead.  L'instruction n'étant pas assez complexe pour justifier la parallèlisation.
 +
 +
 +<code csharp>
 +// Générer des images: https://picsum.photos/3840/2160
 +
 +void Main()
 +{
 +    var path = Directory.GetCurrentDirectory();
 +    var files = Directory.GetFiles(path + @"\pictures", "*.jpg");
 +    
 +    var normalAlteredPath = path + @"\normalAlteredPath";
 +    var parallelAlteredPath = path + @"\parallelAlteredPath";
 +    Directory.CreateDirectory(normalAlteredPath);
 +    Directory.CreateDirectory(parallelAlteredPath);
 +    
 +    ParallelExecutionMode(files, normalAlteredPath);
 +    NormalExecutionMode(files, parallelAlteredPath);
 +}
 +
 +void NormalExecutionMode(string[] files, string alteredPath)
 +{
 +    Stopwatch stopwatch = Stopwatch.StartNew();
 +    foreach (var currentFile in files)
 +    {
 +        var file = Path.GetFileName(currentFile);
 +        using (var fileBitmap = new Bitmap(currentFile))
 +        {
 +            fileBitmap.RotateFlip(RotateFlipType.Rotate270FlipX);
 +            fileBitmap.Save(Path.Combine(alteredPath, file));
 +            Console.WriteLine("Thread {0}", Thread.CurrentThread.ManagedThreadId);
 +        }
 +    }
 +    Console.WriteLine("Normal execution time: {0}", stopwatch.ElapsedMilliseconds);
 +    stopwatch.Stop();
 +}
 +
 +void ParallelExecutionMode(string[] files, string alteredPath)
 +{
 +    Stopwatch stopwatch = Stopwatch.StartNew();
 +
 +    Parallel.ForEach(files, currentFile => {
 +        var file = Path.GetFileName(currentFile);
 +        using (var fileBitmap = new Bitmap(currentFile))
 +        {
 +            fileBitmap.RotateFlip(RotateFlipType.Rotate270FlipX);
 +            fileBitmap.Save(Path.Combine(alteredPath, file));
 +            Console.WriteLine("Thread {0}", Thread.CurrentThread.ManagedThreadId);
 +        }
 +    });
 +
 +    Console.WriteLine("Parallel execution time: {0}", stopwatch.ElapsedMilliseconds);
 +    stopwatch.Stop();
 +}
 +</code>
 +
 +
 +
 +<code csharp>
 +void Main()
 +{
 +    var list = Enumerable.Range(0, 100000000).ToArray();
 +    CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
 +    
 +    ParallelOptions parallelOptions = new ParallelOptions();
 +    parallelOptions.CancellationToken = cancellationTokenSource.Token;
 +    parallelOptions.MaxDegreeOfParallelism = System.Environment.ProcessorCount;
 +    
 +    Console.WriteLine("Press 'x' to cancel");
 +    
 +    Task.Factory.StartNew(() =>
 +    {
 +        if (Console.ReadLine() == "x")
 +        {
 +            cancellationTokenSource.Cancel();
 +        }
 +    
 +        long total = 0;
 +        
 +        try
 +        {
 +            Parallel.For<long>(0, list.Length, parallelOptions, () => 0, (count, parallelLoopState, subtotal) =>
 +            {
 +                Thread.Sleep(200);
 +                parallelOptions.CancellationToken.ThrowIfCancellationRequested();
 +                subtotal += list[count];
 +                return subtotal;
 +            },
 +            (x) =>
 +            {
 +                Interlocked.Add(ref total, x);
 +            });
 +        }
 +        catch (OperationCanceledException ex)
 +        {
 +            Console.WriteLine("Cancelled " + ex.Message);
 +        }
 +        finally
 +        {
 +            cancellationTokenSource.Dispose();
 +        }
 +        Console.WriteLine("The final sum is {0}", total);
 +    });
 +    
 +}
 +</code>
 +
 +===== Continuation with state =====
 +
 +<code csharp>
 +void Main()
 +{
 +    Task<DateTime> task = Task.Run(() => DoSomething());
 +    List<Task<DateTime>> continuationTasks = new List<Task<DateTime>>();
 +    
 +    for (int i = 0; i < 3; i++)
 +    {
 +        task = task.ContinueWith((x, y) => DoSomething(), new Person { Id = i });
 +        continuationTasks.Add(task);
 +    }
 +    
 +    task.Wait();
 +    
 +    foreach (var continuation in continuationTasks)
 +    {
 +        Person person = continuation.AsyncState as Person;
 +        Console.WriteLine("Task finished at " + continuation.Result + ". Person id is {0}", person.Id);
 +    }
 +}
 +
 +static DateTime DoSomething()
 +{
 +    return DateTime.Now;
 +}
 +
 +internal class Person
 +{
 +    public int Id { get; set; }
 +}
 +</code>
 +
 +===== TaskCompletionSource =====
 +
 +<code csharp>
 +void Main()
 +{
 +    TaskCompletionSource<Product> taskCompletionSource = new TaskCompletionSource<Product>();
 +    Task<Product> lazyTask = taskCompletionSource.Task;
 +    
 +    Task.Factory.StartNew(() => {
 +        Thread.Sleep(2000);
 +        taskCompletionSource.SetResult(new Product { Id = 1, Name = "Some name" });
 +    });
 +    
 +    Task.Factory.StartNew(() =>
 +    {
 +        if (Console.ReadLine() == "x")
 +        {
 +            Product result = lazyTask.Result;
 +            Console.WriteLine("Result is {0}", result.Name);
 +        }
 +    });
 +    
 +    Thread.Sleep(5000);
 +}
 +
 +class Product
 +{
 +    public int Id { get; set; }
 +    public string Name { get; set; }
 +}
 +
 +</code>
 +
 +===== PLINQ =====
 +
 +Parallel LINQ:
 +
 +  * Automates parallelization
 +  * Considéré déclaratif plutôt qu'impératif
 +  * Opérateurs qui font en sorte que ce n'est pas parallélisé:
 +    * Take, Select, SelectMany, Skip, TakeWhile, SkipWhile, ElementAt
 +  * Anomalies
 +    * Join, GroupBy, GroupJoin, Distinct, Union, Intersect, Except
 +  * Force parallelism:
 +    * .AsParallel().withExecutionMode(ParallelExecution.ForceParallelism)
 +
 +
 +<code csharp>
 +void Main()
 +{
 +    var list = Enumerable.Range(1, 100000);
 +    var primeNumbers = list
 +                        .AsParallel()
 +                        .Where(IsPrime);
 +    Console.WriteLine("{0} prime numbers", primeNumbers.Count());
 +}
 +
 +bool IsPrime(int x)
 +{
 +    if (x == 1) return false;
 +    if (x == 2) return true;
 +    if (x % 2 == 0) return false;
 +    var boundary = (int)Math.Floor(Math.Sqrt(x));
 +
 +    for (int i = 3; i <= boundary; i += 2)
 +    {
 +        if (x % i == 0)
 +        {
 +            return false;
 +        }
 +    }
 +    return true;    
 +}
 +</code>
 +
 +==== Degree of Parallelism ====
 +
 +<code csharp>
 +void Main()
 +{
 +    List<string> websites = new List<string>();
 +    websites.Add("apple.com");
 +    websites.Add("google.com");
 +    websites.Add("microsoft.com");
 +    
 +    List<PingReply> responses = websites
 +                                    .AsParallel()
 +                                    .WithDegreeOfParallelism(websites.Count())
 +                                    .Select(PingSites)
 +                                    .ToList();
 +    
 +    foreach (var response in responses)
 +    {
 +        Console.WriteLine(response.Address + " " + response.Status + " " + response.RoundtripTime);
 +    }
 +    
 +    Console.ReadLine();
 +}
 +
 +private static PingReply PingSites(string websiteName)
 +{
 +    Ping ping = new Ping();
 +    return ping.Send(websiteName);
 +}
 +</code>
 +
 +
 +
  
 ====== Thread Marshalling ====== ====== Thread Marshalling ======
developpement/dotnet/csharp/introduction.txt · Dernière modification : 2023/10/06 05:06 de sgariepy