Search code examples
c#multithreadingsystem.timers.timer

How to execute threads every min correctly?


This question is in two parts. I have a console application that gets info from several servers and saves this info to a DB. In order to enabel that this executes simultaniously i have used threads. I am trying to make this execution automatic every minute.

Searching stackoverflow i found that this could work:

   var timer = new System.Threading.Timer((e) =>
        {
            var models = ServerHandler.GetServerModels();

            foreach (var m in models)
            {
                ServerHandler.MakeThreads(m);
            }

            Console.WriteLine("Running...");
            Console.WriteLine("Press 'X' to exit or close the window, i : " + i);

            i++;


        }, null, 0, TimeSpan.FromMinutes(1).Seconds);

However this is not working as anticipated, it only executes once. If i change to for example this:

TimeSpan.FromMinutes(0.5).Seconds

Or:

TimeSpan.FromSeconds(30).Seconds

Then it works. What am I doing wrong?

Second part of this question:

When this actually works as I showed above something else happens. The process runs continuously and after 474 threads it crashes and says that the system is out of memory.

I tried using thread sleep for this but when i do that it stops executing after it has runed once.

Including this if it might help:

public static void MakeThreads(ServerModel model)
{
    Thread thread = new Thread(() => SaveServerInfo(model));
    thread.Start();
    //Thread.Sleep(1);
    //thread.Join();

}

How can I make this work?


Solution

  • In your first problem using the .Seconds will only return the seconds value, but you are defining the minutes value as .5, so seconds will always be zero.

    If you want to return the seconds you need to use TotalSeconds

    TimeSpan.FromMinutes(0.5).TotalSeconds
    

    and in the timespan you are using you are supposed to define the milliseconds. So you're getting a huge number of threads because its running every 30 millseconds instead of every 30000 milliseconds.

    So use

    TimeSpan.FromMinutes(0.5).TotalMilliseconds
    

    or what i always find easier

    (int)(1000 * 60 * 0.5)  // Then you just replace the 0.5 with the number of seconds.