0

The usecase is pretty simple

I have this for starting the threads

Main class

 for (int x = 1; x <= numThreads; x++)
    {
        new ThreadComponent(x, this, creator).init();
    }

Thread class

public void init()
{
    thread = new Thread(doLogic);
    thread.IsBackground = true;
    thread.Start();
}
void doLogic()
{
    while (true)
    {
        
            doLogicGetData();
    }

}

Idea is that thread execution takes approx. 6 seconds I want 6 threads that start at 1 second interval

 1------1------

  2------2------

   3------3------ 

    4------4------

     5------5------

      6------6------ 

I saw a lot of ideas about using timers or cronjobs but i do not know how to implement them in a proper way

cUser
  • 392
  • 8
  • 25
  • 5
    can't you just make the main thread sleep for 1 second each time it loops to create a new one? – ADyson Sep 25 '20 at 09:16
  • A simple timer to start new job every second should do. If you are allowed to block the caller, then `Thread.Sleep(1000)` is same good. – Sinatr Sep 25 '20 at 09:19
  • Does this answer your question? [How to add a delay for a 2 or 3 seconds](https://stackoverflow.com/questions/5449956/how-to-add-a-delay-for-a-2-or-3-seconds) – Sinatr Sep 25 '20 at 09:22
  • @Sinatr Thread.sleep() i read that is not a recommended solution – cUser Sep 25 '20 at 09:29
  • @npinti can you have a c# suggestion for that :) – cUser Sep 25 '20 at 09:31
  • @ADyson i can but apparently is not stable enough because is not exactly 6 seconds per loop – cUser Sep 25 '20 at 09:33
  • 1
    *"i read that is not a recommended solution"* - this is nonsense in given context. If your code would be asynchronous, then `Task.Delay` would be indeed preferable. – Sinatr Sep 25 '20 at 09:36
  • _"is not exactly 6 seconds per loop"_ ...why does that matter? You said you wanted them to _start_ at 1 second intervals. So thread 1 starts, then 1 second later thread 2 starts, etc. That has nothing to do with 6 seconds. – ADyson Sep 25 '20 at 09:36
  • @npinti what does Java have to do with this?? I don't understand your suggestion. – ADyson Sep 25 '20 at 09:38
  • Do you have a specific reason for using the Thread class directly, or could you use the TPL model? – jeroenh Sep 25 '20 at 09:44
  • @jeroenh that was the way that i find convenient to run the code in parallel and i do not know about TPL – cUser Sep 25 '20 at 09:50
  • 3
    Btw, instead of synchronizing only start of tasks consider to synchronize their work. Otherwise it's likely their frequence will overlap, it could happens what all 6 tasks will be calling `doLogicGetData` at same time. – Sinatr Sep 25 '20 at 09:50
  • @Sinatr can you provide an example :) ? – cUser Sep 25 '20 at 09:53
  • Timer is the best for such a case. It just have to tell certain task to continue, while others are either blocked or finishing their current job. This way you will persist this 1s delays and overal 6 seconds period. – Sinatr Sep 25 '20 at 10:01

1 Answers1

3

A more 'canonical' way to tackle this problem in .Net is using the Task Parallel Library instead of manually controlling threads. The console program below illustrates how you would run 6 threads on background threads, with a one second delay between them.

class Program
{
    public async static Task Main()
    {
        var cts = new CancellationTokenSource();

        List<Task> tasks = new List<Task>();

        for (int i = 0; i < 6; i++)
        {
            tasks.Add(Task.Run(() => DoWork(cts.Token), cts.Token));
            await Task.Delay(1000);
        }

        Console.WriteLine("Press ENTER to stop");
        Console.ReadLine();
        Console.WriteLine("Waiting for all threads to end");
        cts.Cancel();
        await Task.WhenAll(tasks);
    }

    public static void DoWork(CancellationToken token)
    {
        while (!token.IsCancellationRequested)
        {
            Console.WriteLine($"Doing work on thread {Thread.CurrentThread.ManagedThreadId}");
            Thread.Sleep(10000); // simulating 10 seconds of CPU work;
        }
        Console.WriteLine($"Worker thread {Thread.CurrentThread.ManagedThreadId} cancelled");
    }
}

Asynchronous programming using the Task Parallel Library is explained pretty well in the documentation

jeroenh
  • 26,362
  • 10
  • 73
  • 104
  • await Task.WhenAll(tasks) is it necessary ? Cos i want if task 1 finish but 6h not to start another execution of it – cUser Sep 25 '20 at 10:02
  • You would need to break out of the loop to stop further tasks being generated. You could do: `if (tasks.Any(t => t.IsCompleted)) break;` – Johnathan Barclay Sep 25 '20 at 10:09
  • You can also use `Task.WhenAny(tasks)` instead of `Task.WhenAll()`. Check the documentation, e.g. at https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/start-multiple-async-tasks-and-process-them-as-they-complete – jeroenh Sep 25 '20 at 14:12