exercice thread en c#
static void Main(string[] args)
{
Task t = RunAsync();
t.Wait();
Console.In.ReadLine();
}
public static async Task RunAsync()
{
using (SemaphoreSlim verrouRessource = new SemaphoreSlim(0, 1))// on crée un sémaphore qui ne peut libérer qu'une ressource mais qui la marque comme occupée pour l'instant
{
Queue<int> ressourcePartage = new Queue<int>();
//on prépare les tâches
List<Task> taches = new List<Task>();
Console.Out.WriteLine("Start write");
taches.Add(EnvoieDansLaFile(ressourcePartage, verrouRessource));
Console.Out.WriteLine("Start read");
taches.Add(LireLaFile(ressourcePartage, verrouRessource));
verrouRessource.Release();//on peut commencer
await Task.WhenAll(taches.ToArray());
}
}
public static async Task EnvoieDansLaFile(Queue<int> file, SemaphoreSlim verrou)
{
for (int i = 0; i < 15; i++)
{
await verrou.WaitAsync();//on attendq que la ressource soit libre
file.Enqueue(i);//on utilise la ressource
verrou.Release();//on dit qu'on a finit d'utiliser la ressource pour l'instant
System.Console.Out.WriteLine("On a ajouté " + i.ToString());
Thread.Sleep(100);//on attend histoire que l'exemple soit utile
}
}
public static async Task LireLaFile(Queue<int> file, SemaphoreSlim verrou)
{
bool first = true;
await verrou.WaitAsync();//on va utiliser la ressource
while (file.Count > 0 || first)
{
// pour éviter le cas où cette tâche serait exécutée avant la première fois où on met un entier
if (file.Count > 0 && first)
{
first = false;
}
System.Console.Out.WriteLine(file.Dequeue());
verrou.Release();//on enlève le verrou
System.Console.Out.WriteLine("on attend le prochain tour");
Thread.Sleep(150);
await verrou.WaitAsync();//on va utiliser la ressource au prochain tour de boucle
}
}