C# c中For循环的时间延迟#

C# c中For循环的时间延迟#,c#,timer,C#,Timer,如何在循环中使用特定旋转后的时间延迟? 假设: 用于(int i=0;i使用(从System.Threading): for(int i=0;i如果您希望在每8次迭代后睡眠,请尝试以下方法: for (int i = 0; i < 64; i++) { //... if (i % 8 == 7) Thread.Sleep(1000); //ms } for(int i=0;i

如何在循环中使用特定旋转后的时间延迟? 假设:

用于(int i=0;i使用(从System.Threading):


for(int i=0;i如果您希望在每8次迭代后睡眠,请尝试以下方法:

for (int i = 0; i < 64; i++)
{
    //...
    if (i % 8 == 7)
        Thread.Sleep(1000); //ms
}
for(int i=0;i<64;i++)
{
//...
如果(i%8==7)
Thread.Sleep(1000);//毫秒
}

您可能还希望只考虑使用
计时器,而不是在循环中暂停当前线程


它将允许您在一段时间后执行某些代码块(重复或不重复)。如果没有更多的上下文,则很难确定这是否最适合您的情况,或者您将如何相应地更改解决方案。

有很多方法可以做到这一点:

  • 方法一:犯罪可怕:忙碌等待:

    DateTime timetostartupReach=无论什么;

    while(DateTime.Now

这是一件可怕的事情;操作系统会认为你正在做有用的工作,并会指派一个CPU来做除此之外的其他事情。除非你知道旋转只会持续几微秒,否则永远不要这样做。基本上,当你这样做时,你已经雇了人帮你看时钟;这是不经济的

  • 方法二:糟糕透顶:睡线
睡眠线程也是一件可怕的事情,但不如加热CPU那么可怕。睡眠线程告诉操作系统“这个应用程序的线程应该停止响应事件一段时间,什么也不做”。这比雇人帮你看时钟要好;现在你雇了人帮你睡觉

  • 方法三:将工作分解成更小的任务。创建一个计时器。如果需要延迟,而不是执行下一个任务,则创建一个计时器。当计时器触发勾号事件时,选择您停止的任务列表
这可以有效地利用资源;现在你正在雇佣一个人来煮鸡蛋,而鸡蛋在煮的时候,他们可以做吐司

然而,编写程序将工作分解成小任务是一件痛苦的事情

  • 方法四:使用C#5对异步编程的支持;等待延迟任务,让C#编译器负责重新构造程序以使其高效
缺点当然是C#5目前只处于测试阶段


注意:从Visual Studio 2012开始,C#5正在使用。如果您使用的是VS 2012或更高版本,则可以使用异步编程。

这是我提出的实现。它是通用的,因此您可以轻松地在您的用例中重用它。(它与@Servy建议的一致)

它打印了这个:

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

尝试这个更简单的版本,不依赖于async、await或TPL

  • 生成50个方法调用
  • 睡20秒
  • 检查20个或x个项目 这些都是完整的
  • 如果没有,再睡20秒
  • 如果是,则恢复循环
  • 此处编码

     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);
                            }
                        }
                    }
                }
    

    有一次我需要写一个程序,这个程序非常敏感,需要精确的计时(大约纳秒)

    我使用了各种各样的东西,比如
    Thread.Sleep()
    ,Timer和…但是没有一个能满足我的需要,所以我用这些代码来延迟:

    var stopWatch = new Stopwatch();
    for(int i = 0 ; i<64;i++)
    {
    stopWatch.Restart();
    while (stopWatch.ElapsedMilliseconds <= 1000)
    {
    
    }
    }
    
    var stopWatch=new stopWatch();
    
    对于(int i=0;i+1)两个答案,如果使用错误,它也会阻止UI线程。这将在第一次迭代后休眠。系统时钟是否会将分辨率限制在~15ms?否。秒表甚至可以精确到1ms。我们正在一个非常时间敏感的项目中使用它。
    var numbers = Enumerable.Range(1, 10).ToList();
    var interval = 1000; // 1000 ms delay
    numbers.ForEachWithDelay(i => Task.Run(() => Console.WriteLine(i + " @ " + DateTime.Now)), interval);
    
    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
    
     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);
                            }
                        }
                    }
                }
    
    function DoWork()
    //Do work in a sep thread.
    cnt--;
    )
    
    var stopWatch = new Stopwatch();
    for(int i = 0 ; i<64;i++)
    {
    stopWatch.Restart();
    while (stopWatch.ElapsedMilliseconds <= 1000)
    {
    
    }
    }