Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Run and stop a method for a minute

timer1= new System.Windows.Forms.Timer();
timer1.Interval =60000; // 1 min
timer1.Start();
MyMethodName();
timer1.Stop();

MyMethodName()

-has a for loop for 90,000 entries (and some validations inside that for loop).

for (int i = 0; i <= 90000; i++)
{
 //validations go here

}

When the time in timer1 is done for a minute, i want to stop executing other entries in the for loop. For example, if 45,000 entries are done in a minute, i want to stop executing the method ie. stop the method after a minute.

However the above timer code, executes till all the 90000 records are done looping inside the for loop, somehow the method doesn't run for a minute? Any help?

like image 535
Sharpeye500 Avatar asked Mar 23 '23 06:03

Sharpeye500


2 Answers

Two things. Firstly Your timer code is not actually connected to the running of MyMethodName. A timer is designed to run processes when the time has elapsed (and possibly at regular intervals depending on how it is set up.

Secondly and more to the point of your question to abort a loop you have to put code inside the loop. The key would be to have a stopwatch or similar start before your loop and then at the beginning of your loop check how much time has elapsed. If it is a minute or more then break;.

The key thing to note is that you will not stop exactly on a minute but you will finish the iteration of the loop that is running when the minute expires and then stop. This is usually what you want since stopping processing midway through something may cause nasty side effects.

Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
for (int i =0; i<=90000; i++)
{
    if (stopwatch.Elapsed>TimeSpan.FromSeconds(5))
        break;
    Console.WriteLine(i);
    Thread.Sleep(1000);
}

Note that Thread.Sleep is there just because otherwise I get through all 90000 iterations too quickly. ;-)

like image 88
Chris Avatar answered Apr 02 '23 07:04

Chris


So you would likely need a much different implementation. Consider this:

public class MyForm
{
    private BackgroundWorker _worker;

    public MyForm()
    {
        _worker = new BackgroundWorker();
        _worker.DoWork += (s, args) =>
        {
            var timer = Stopwatch().StartNew();
            do
            {
                // do something
            } while (timer.ElapsedMilliseconds < 60000)
        };
    }
}

and then when you want to run it:

_worker.RunWorkerAsync();

However, you could make it even more robust. You could pass the time in like this:

_worker.RunWorkerAsync(60000);

and then in the DoWork handler, do this:

while (timer.ElapsedMilliseconds < (int)args.Argument)

Further, with the BackgroundWorker, you could support cancellation. Just set the WorkerSupportsCancellation flag to true and then in the condition do this:

while (timer.ElapsedMilliseconds < (int)args.Argument && !_worker.CancellationPending)

so, if necessary, you could do this:

_worker.CancelAsync();
like image 24
Mike Perrenoud Avatar answered Apr 02 '23 07:04

Mike Perrenoud