C# thread

Exemple 1 - 1 thread


  public void run1()
 {
     Thread t = new Thread(() =>
     {
         Console.WriteLine("Thread démarré !");
         Thread.Sleep(2000); // bloque 2 secondes
         Console.WriteLine("Thread terminé !");
     });

     t.Start(); // lance le thread
     Console.WriteLine("Main continue pendant que le thread travaille...");
     for (int i = 0; i < 10; i++)
     {
         Console.WriteLine($"Wait thread {i}");
     }
     t.Join(); // attend la fin du thread
     Console.WriteLine("Programme terminé !");
 }

 void Work(string nom, int delai)
 {
     Console.WriteLine($"Thread {nom} start");
     Thread.Sleep(delai);
     Console.WriteLine($"Thread {nom} end");
 }

 public void run1()
 {
     Thread t1 = new Thread(() => Work("A", 2000));
     Thread t2 = new Thread(() => Work("B", 1000));

     t1.Start();
     t2.Start();

     Console.WriteLine("Start waiting threads (join)");
     t1.Join();
     t2.Join();

     Console.WriteLine("All threads finished !");
 }

Exemple 2 - threadpool


  public static void run3()
  {
      ThreadPool.QueueUserWorkItem(_ =>
      {
          Console.WriteLine("Travail dans le ThreadPool");
          Thread.Sleep(1000);
          Console.WriteLine("Travail terminé");
      });

      Console.WriteLine("Main continue...");
      Thread.Sleep(2000); // attendre pour voir le résultat
  }      

Exemple 3 - avec return

  
 public void run1()
 {
     var tcs = new TaskCompletionSource();

     Thread t = new Thread(() =>
     {
         int result = 42;
         Thread.Sleep(10000);
         tcs.SetResult(result);
     });

     t.Start();

     int result = tcs.Task.Result;
     Console.WriteLine($"Résultat : {result}");
     Console.WriteLine("end");
 }

  int Work(string nom, int delai)
 {
     Console.WriteLine($"Thread {nom} start");
     Thread.Sleep(delai);
     Console.WriteLine($"Thread {nom} end");
     return delai * 3;
 }

 public void run2()
 {
     var tcs = new TaskCompletionSource<int>();

     Thread t1 = new Thread(() =>
     {
         int r = Work("A", 2000);
         tcs.SetResult((int)r);
     });

     t1.Start();
     int result = tcs.Task.Result;

     Console.WriteLine($"result {result}");
 }

Exemple 4 - many threads avec return


  public void run3()
 {

     int result1 = 0;
     int result2 = 0;

     Thread t1 = new Thread(() => result1 = Work("A", 2000));
     Thread t2 = new Thread(() => result2 = Work("B", 3000));

     t1.Start();
     t2.Start();

     Console.WriteLine("Start waiting threads (join)");

     t1.Join();
     t2.Join();

     Console.WriteLine("All threads finished !");
     Console.WriteLine($"Resultat A = {result1}");
     Console.WriteLine($"Resultat B = {result2}");
 }

 public async Task run3Async()
 {
     var tcs1 = new TaskCompletionSource();
     var tcs2 = new TaskCompletionSource();

     Thread t1 = new Thread(() => tcs1.SetResult(Work("A", 2000)));
     Thread t2 = new Thread(() => tcs2.SetResult(Work("B", 3000)));

     t1.Start();
     t2.Start();

     int result1 = await tcs1.Task;
     int result2 = await tcs2.Task;

     Console.WriteLine("All threads finished !");
     Console.WriteLine($"Resultat A = {result1}");
     Console.WriteLine($"Resultat B = {result2}");
 }

 public void RunN(int n)
{
    Thread[] threads = new Thread[n];
    int[] results = new int[n];

    for (int i = 0; i < n; i++)
    {
        int index = i; // capture correcte
        int delay = 1000 + index * 500; // exemple : delai variable

        threads[i] = new Thread(() =>
        {
            results[index] = Work($"T{index}", delay);
        });

        // threads[i].Start();
    }

    foreach (var t in threads)
    {
        t.Start();
    }

    Console.WriteLine("Waiting for all threads...");

    // Attente de tous les threads
    for (int i = 0; i < n; i++)
        threads[i].Join();

    Console.WriteLine("All threads finished!");

    // Affichage des résultats
    for (int i = 0; i < n; i++)
        Console.WriteLine($"Result Thread {i} = {results[i]}");
}

 public async Task RunNAsync(int n)
{
    var tcsList = new TaskCompletionSource[n];
    var threads = new Thread[n];

    for (int i = 0; i < n; i++)
    {
        int index = i;
        tcsList[index] = new TaskCompletionSource();
        int delay = 1000 + 500 * index;

        threads[index] = new Thread(() =>
        {
            int r = Work($"T{index}", delay);
            tcsList[index].SetResult(r);
        });

        threads[index].Start();
    }

    int[] results = await Task.WhenAll(tcsList.Select(t => t.Task));

    Console.WriteLine("All threads finished!");
    for (int i = 0; i < results.Length; i++)
        Console.WriteLine($"Result Thread {i} = {results[i]}");
}

exception


static async Task<int> CalculerAsync(int x)
{
    if (x < 0)
        throw new ArgumentException("x ne peut pas être négatif");

    await Task.Delay(500);
    return x * x;
}

// gestion simple
public static async Task run1()
{
    try
    {
        int resultat = await CalculerAsync(-5);
        Console.WriteLine($"Résultat : {resultat}");
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Erreur capturée : {ex.Message}");
    }
}


public static async Task run2()
{
    var t1 = CalculerAsync(5);
    var t2 = CalculerAsync(-3); // va échouer
    int[] resultats = null;

    try
    {
        resultats = await Task.WhenAll(t1, t2);
        Console.WriteLine($"Résultats : {string.Join(", ", resultats)}");
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Erreur capturée : {ex.Message}");
    }

    Console.WriteLine($"t1 terminé : {t1.Status}, t2 terminé : {t2.Status}");
    if ( resultats != null )
        Console.WriteLine($"Résultats : {string.Join(", ", resultats)}");
}


// plusieurs exceptions
public static async Task run3()
{
    var t1 = CalculerAsync(-1);
    var t2 = CalculerAsync(-2);

    try
    {
        await Task.WhenAll(t1, t2);
    }
    catch
    {
        Console.WriteLine("Plusieurs erreurs !");
        if (t1.Exception != null)
        {
            foreach (var ex in t1.Exception.InnerExceptions)
                Console.WriteLine($"t1 erreur : {ex.Message}");
        }

        if (t2.Exception != null)
        {
            foreach (var ex in t2.Exception.InnerExceptions)
                Console.WriteLine($"t2 erreur : {ex.Message}");
        }
    }
}

public static void run5()
{
    Task<int> t = CalculerAsync(-10);
    t.ContinueWith(task => {
        if (task.IsFaulted)
            Console.WriteLine($"Erreur : {task.Exception?.InnerException?.Message}");
        else
            Console.WriteLine($"Résultat : {task.Result}");});
}