Click here to Skip to main content
15,894,343 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
Say i have a for loop. I want the program to automatically 'continue' the for loop if the time spent inside one loop of the for loop is more than say 10 minutes. I want to run some additional commands to clean up the code too. Any Ideas how I can implement this ?

I can manage even if the loop breaks.

FYI,
My problem is that my service picks up a row from an SQL server and runs some logics on it but the logics sometimes goes into an infinite loop. Due to this I need to manually remove the row from the SQL server and restart the service.

Sorry for Bad English
Posted
Updated 30-Oct-13 21:47pm
v2

A) You could try this approach:

C#
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;

class Program
{
    static long counter = 0;

    static void DoLongRunningTask(CancellationToken token)
    {
        token.ThrowIfCancellationRequested();

        Stopwatch stopwatch = new Stopwatch();
        stopwatch.Start();

        while (true)
        {
            Console.Write("{0}\r",counter++);
            if (token.IsCancellationRequested)
            {
                stopwatch.Stop();
                Console.WriteLine("\nCanceled. Cleaning up. Time elapsed: {0}", stopwatch.Elapsed);
                token.ThrowIfCancellationRequested();
            }
        }
    }

    static void Main()
    {
        var tokenSource = new CancellationTokenSource();
        var token = tokenSource.Token;
        var task = new Task(() => DoLongRunningTask(token), token);

        Console.Write("Task ");
        task.Start();
        tokenSource.CancelAfter(10000);
        Console.Write("started and should run 10 seconds\n");

        try  { task.Wait(); }
        catch { }

        Console.WriteLine("Status:      {0}", task.Status);
        Console.WriteLine("IsCanceled:  {0}", task.IsCanceled);
        Console.WriteLine("IsCompleted: {0}", task.IsCompleted);

        task.Dispose();

        Console.WriteLine("Finished. Press any key.");
        Console.ReadKey();
    }
}

Please note, that this is no brute-force cancellation. It won't "kill" the task, it requires neat finishing. So if you are blocked inside one operation - let's call it atomic in this sense -, this won't help you. (Source: http://www.blackwasp.co.uk/TaskCancellation_2.aspx[^])

You can however not wait in this manner for the task to complete, you could do anything else in your service in the meantime.

An interesting article, but I couldn't get it working in a few minutes: http://blogs.msdn.com/b/pfxteam/archive/2011/11/10/10235834.aspx[^]

B)
Using workers: http://msdn.microsoft.com/en-us/library/7a2f3ay4(v=vs.90).aspx[^]

C)
For threading, you could use this approach: http://dotnet-snippets.com/snippet/end-thread-after-timeout/656[^], however you have top be careful with aborting treads. (see also: http://msdn.microsoft.com/en-us/library/5b50fdsz.aspx[^])

Anyway, you should be very careful with cleaning your resources when you stop such an execution.
 
Share this answer
 
Comments
rohith naik 31-Oct-13 9:10am    
Thanks man, will get back to you after going through this.
Zoltán Zörgő 31-Oct-13 9:19am    
Ok. Please note also, that except from the "tread.Abort" method all others will need your worker logic to check if there was any cancellation issued. Trough if your logic is not an iteration or the iteration itself is long running, you have to check this status often.
Version B need some extra logic for timing, but a simple Timer object would be enough.
BillWoodruff 1-Nov-13 0:54am    
Excellent answer. +5
Zoltán Zörgő 1-Nov-13 2:42am    
Thank you.
rohith naik 6-Nov-13 9:15am    
I would after trying all approaches, i would HIGHLY recommend not using the task.wait() as it causes the application to become VERY unstable. The thread.abort method seems to be the best method. I ended up going for a !t.join(...) clause as it seemed the best way with fewest errors. Needed a few mods to the calling function to include the try catch blocks to catch the abort thread exception but seems to be worth it. Thanks Man
Try this:
C#
using System.Diagnostics; // add this line to the top of your code file

C#
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < 10000; i++)
{
    if (sw.Elapsed.TotalMinutes >= 10)
    {
        // some actions before breaking out the loop
        sw.Stop();
        break;
    }
    // other actions here
}
if (sw.IsRunning)
{
    sw.Stop();
}

Hope this helps.
 
Share this answer
 
Comments
rohith naik 31-Oct-13 3:58am    
This not what i want. I want the program to 'automatically detect' if a particular iteration is taking more than 10 minutes. For example ,
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < 10000; i++)
{
if (sw.Elapsed.TotalMinutes >= 10)
{
// some actions before breaking out the loop
sw.Stop();
break;
}
MyFunction.Run(i);
}
if (sw.IsRunning)
{
sw.Stop();
}
If a loop in MyFunction.Run(i) takes more than 10 minutes this will not break/continue my loop. What I want to say is that the program must not wait for the loop to end but must take affirmative action as soon as 10 minutes is up. your code waits for it to end the current iteration and then checks for the condition in the next iteration. I think we need to use threads but i'm noob in that.

Thanks for the reply though.
Thomas Daniels 31-Oct-13 4:09am    
OK, thanks for the explanation. I'll try to find a way to do that.
Thomas Daniels 31-Oct-13 4:19am    
Then you should use my code in your MyFunction.Run method.
rohith naik 31-Oct-13 5:01am    
Here was is a solution i thought of but I am having difficulty implementing it. I start 2 threads from my main loop. I make one thread sleep for 10 minutes and the other thread actually run my function. If the function returns a value before my sleeping thread then it is fine else abort the thread. But implementing it seems very hard.
Thomas Daniels 31-Oct-13 5:04am    
The problem is that it is not really possible to abort a thread: you can use the Thread.Abort function, but you can't be 100% sure that this really aborts the thread. So, in your second thread, you must check whether the first thread said that the second thread should stop. The only way to abort a thread is to look at the value of a specific bool, and if the value of that bool is true, break out the loop.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900