Laden...

Weiteren Task starten während der andere noch beschäftig ist

Erstellt von degri2006 vor 2 Jahren Letzter Beitrag vor 2 Jahren 268 Views
D
degri2006 Themenstarter:in
21 Beiträge seit 2009
vor 2 Jahren
Weiteren Task starten während der andere noch beschäftig ist

Hallo,
ich habe eine kleines Problem mit Tasks in C#.
Ich habe eine Queue mit ganzen Zahlen. Diese Zahlen sollen in einem Worker aus der Queue geholt werden.
Der Worker soll sich dann entsprechend schlafen legen. Es gibt in dem Beispiel zwei Tasks/Threads.
In der ersten Runde werden 3 und 10 aus der Queue geholt und die Tasks legen sich für 3 und 10 Sekunden schlafen.
In dem Fall wird aufgrund WaitAll in der ersten Runden auf den Task gewartet, der 10 Sekunde schläft. Wie kann ich veranlassen, dass während der eine Task 10 Sekunden schläft der nächste Task gestartet wird nachdem der 3 Sekunden Task fertig ist? Wichtig ist, dass alle Tasks korrekt beendet und nicht abgebrochen werden.


using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Threading;
using System.Collections.Concurrent;

namespace ThreadPoolApplication
{
    class Program
    {
        
        static void Main(string[] args)
        {
            ConcurrentQueue<int> myQueue = new ConcurrentQueue<int>();
            List<Task> TaskList = new List<Task>();
            myQueue.Enqueue(3);
            myQueue.Enqueue(10);
            myQueue.Enqueue(2);
            myQueue.Enqueue(4);

            while (myQueue.Count > 0)
            {

                int NumberOfThreads = 2;
                for (int i = 0; i < NumberOfThreads; ++i)
                {
                    TaskList.Add(Task.Factory.StartNew(() => { Worker(myQueue); }));

                }
                Task.WaitAll(TaskList.ToArray());
                TaskList.Clear();
            }
        }

        static void Worker(ConcurrentQueue<int> myQueue)
        {
            int element;
            
            while (!myQueue.TryDequeue(out element))
            {
                Console.WriteLine("Queue ist gesperrt");
                Thread.Sleep(5);
            }
            Console.WriteLine($"Schlafe für {element} Sekunden");
            Thread.Sleep(TimeSpan.FromSeconds(element));
            Console.WriteLine($"Aufgewacht nach {element} Sekunden");
        }
        
    }
}


C
2.121 Beiträge seit 2010
vor 2 Jahren

Klar, wenn du auf beide wartest wird auch auf beide gewartet 🙂
Erstelle die zwei Tasks nur einmalig und lass die selbst in einer Schleife schauen ob noch was in der Queue ist.

"Queue ist gesperrt"

Eigentlich ist die Queue hier ja nur leer, aber nicht gesperrt.

16.833 Beiträge seit 2008
vor 2 Jahren

Davon abgesehen würde man in einem modernen .NET Umfeld das über Channels lösen.
An Introduction to System.Threading.Channels | .NET Blog