sabisabi
sabisabi

Reputation: 1511

Start several functions at the same time in every x seconds?

I know how to start a function in x seconds, its something like this:

private Timer timer1; 
public void InitTimer()
{
    timer1 = new Timer();
    timer1.Tick += new EventHandler(timer1_Tick);
    timer1.Interval = 2000; // in miliseconds
    timer1.Start();
}

private void timer1_Tick(object sender, EventArgs e)
{
    function1();
    function2();
    function3();
}

The problem here: The functions cannot run at the same time. Function2 can only run if Function1 is done. But I want them running at the same time. Thats why I could do this:

private void timer1_Tick(object sender, EventArgs e)
{
   Parallel.Invoke(
     () => Function1(),
     () => Function2(),
     () => Function3()
   );
}

Is this the smartest way to do it in c#? What I dont understand with Parallel.Invoke: what if my timer is set for 5 sec and after 5 sec function1,2 and 3 are not done but I call them all again. Do I start these functions in a new thread? Are there after some calls x-threads running function1() (at the same time)? Wondering is that really healthy.

If somebody would like to get more information: function1 is just there to copy file x from folder a to b, function2 is only there to read all files from folder b and save the information and function3 is only there to check the connection and if there is a connection send the appropriate file to somebody.

Any suggestions to the code? Thank you

Upvotes: 1

Views: 2608

Answers (3)

Marcelo De Zen
Marcelo De Zen

Reputation: 9497

Use System.Threading.Timer to schedule the callback on a ThreadPool thread, so you don't need to create a new task. It also allows you to control the intervals to prevent the overlap of callbacks.

// fired after 5 secs, but just once.
_timer = new System.Threading.Timer(Callback, null, 5000, Timeout.Infinite);

// on the callback you must re-schedule the next callback time;
private void Callback(Object state) {
   Function1();
   Function2();

   // schedule the next callback time 
   _timer.Change(5000, Timeout.Infinite);
}

Upvotes: 1

Colin Smith
Colin Smith

Reputation: 12540

Have you looked at Tasks?

You could do something like this:

Task[] tasks = new Task[3];
tasks[0] = Task.Factory.StartNew(() => Function1());
tasks[1] = Task.Factory.StartNew(() => Function2());
tasks[2] = Task.Factory.StartNew(() => Function3());
Task.WaitAll(tasks);

The above will allow you to run the functions in parallel, which is what you imply you want.

If you don't want to block inside the timer1_Tick waiting for all the Tasks to complete, then don't use WaitAll....instead you could check if the Tasks have completed by checking IsCompleted on the Tasks when your timer gets fires again....then decide whether to issue the next batch of functions.

Upvotes: 0

L.B
L.B

Reputation: 116118

Parallel.Invoke runs all your functions in parallel. Since function2 shouldn't run before function1, create a task that runs them in background but sequentially.

Task.Factory.StartNew(() =>
{
    function1();
    function2();
    function3();
});

what if my timer is set for 5 sec and after 5 sec function1,2 and 3 are not done

you can use a bool to see whether they are completed or not.

Upvotes: 2

Related Questions