Time delay in For loop in c#

前端 未结 7 1294
伪装坚强ぢ
伪装坚强ぢ 2020-12-06 01:18

how can i use a time delay in a loop after certain rotation? Suppose:

for(int i = 0 ; i<64;i++)
{
........
}

i want 1 sec delay after ea

相关标签:
7条回答
  • 2020-12-06 02:01

    You may also want to just look into using a Timer rather than pausing the current thread in a loop.

    It will allow you to execute some block of code (repeatedly or not) after an interval of time. Without more context it would be hard to say for sure if that's best in your situation or how you would go about altering your solution accordingly.

    0 讨论(0)
  • 2020-12-06 02:04

    If you want a sleep after each 8 iterations, try this:

    for (int i = 0; i < 64; i++)
    {
        //...
        if (i % 8 == 7)
            Thread.Sleep(1000); //ms
    }
    
    0 讨论(0)
  • 2020-12-06 02:04

    Try this simpler version without dependency on async or await or TPL.

    1. Spawns 50 method calls ,
    2. sleeps for 20 secs,
    3. checks it 20 or x items are complete.
    4. if not sleeps again for 20 secs
    5. if yes resumes loop

    Code here

     foreach (var item in collection)
                {
                    if (cnt < 50)
                    {
                        cnt++;
                        DoWork(item);
                    }
                    else
                    {
                        bool stayinLoop = true;
                        while (stayinLoop)
                        {
                            Thread.Sleep(20000);
                            if (cnt < 30)
                            {
                                stayinLoop = false;
                                DoWork(item);
                            }
                        }
                    }
                }
    

    Do work in a separate thread, so that sleep doesn't block you, could be a background worker , Begin , End method of webrequest or optionally an async task or Task.Run()

    function DoWork()
    //Do work in a sep thread.
    cnt--;
    )
    
    0 讨论(0)
  • 2020-12-06 02:07

    Here is the implementation I came up with. It's generic, so you can easily reuse it for your use case. (it aligns with what @Servy suggested)

    public static async Task ForEachWithDelay<T>(this ICollection<T> items, Func<T, Task> action, double interval)
    {
        using (var timer = new System.Timers.Timer(interval))
        {
            var task = new Task(() => { });
            int remaining = items.Count;
            var queue = new ConcurrentQueue<T>(items);
    
            timer.Elapsed += async (sender, args) =>
            {
                T item;
                if (queue.TryDequeue(out item))
                {
                    try
                    {
                        await action(item);
                    }
                    finally
                    {
                        // Complete task.
                        remaining -= 1;
    
                        if (remaining == 0)
                        {
                            // No more items to process. Complete task.
                            task.Start();
                        }
                    }
                }
            };
    
            timer.Start();
    
            await task;
        }
    }
    

    And then use it as so:

    var numbers = Enumerable.Range(1, 10).ToList();
    var interval = 1000; // 1000 ms delay
    numbers.ForEachWithDelay(i => Task.Run(() => Console.WriteLine(i + " @ " + DateTime.Now)), interval);
    

    which prints this:

    1 @ 2/2/2016 9:45:37 AM
    2 @ 2/2/2016 9:45:38 AM
    3 @ 2/2/2016 9:45:39 AM
    4 @ 2/2/2016 9:45:40 AM
    5 @ 2/2/2016 9:45:41 AM
    6 @ 2/2/2016 9:45:42 AM
    7 @ 2/2/2016 9:45:43 AM
    8 @ 2/2/2016 9:45:44 AM
    9 @ 2/2/2016 9:45:45 AM
    10 @ 2/2/2016 9:45:46 AM
    
    0 讨论(0)
  • 2020-12-06 02:11

    Use Thread.Sleep (from System.Threading):

    for(int i = 0 ; i<64;i++)
    {
         if(i % 8 == 0)
            Thread.Sleep(1000);
    }
    
    0 讨论(0)
  • 2020-12-06 02:12

    There are a lot of ways to do that:

    • Method one: Criminally awful: Busy-wait:

      DateTime timeToStartUpAgain = whatever;

      while(DateTime.Now < timeToStartUpAgain) {}

    This is a horrible thing to do; the operating system will assume that you are doing useful work and will assign a CPU to do nothing other than spinning on this. Never do this unless you know that the spin will be only for a few microseconds. Basically when you do this you've hired someone to watch the clock for you; that's not economical.

    • Method two: Merely awful: Sleep the thread.

    Sleeping a thread is also a horrible thing to do, but less horrible than heating up a CPU. Sleeping a thread tells the operating system "this thread of this application should stop responding to events for a while and do nothing". This is better than hiring someone to watch a clock for you; now you've hired someone to sleep for you.

    • Method three: Break up the work into smaller tasks. Create a timer. When you want a delay, instead of doing the next task, make a timer. When the timer fires its tick event, pick up the list of tasks where you left off.

    This makes efficient use of resources; now you are hiring someone to cook eggs and while the eggs are cooking, they can be making toast.

    However it is a pain to write your program so that it breaks up work into small tasks.

    • Method four: use C# 5's support for asynchronous programming; await the Delay task and let the C# compiler take care of restructuring your program to make it efficient.

    The down side of that is of course C# 5 is only in beta right now.

    NOTE: As of Visual Studio 2012 C# 5 is in use. If you are using VS 2012 or later async programming is available to you.

    0 讨论(0)
提交回复
热议问题