在C#中的特定时间后退出循环

sil*_*oon 11 c# benchmarking

我的项目(C#,VS2010,.NET 4.0)要求特定for循环必须在200毫秒内完成.如果没有那么它必须在此持续时间之后终止而不执行剩余的迭代.循环通常i = 0达到约500,000到700,000,因此总循环时间变化.

我读过以下类似的问题,但在我的案例中没有帮助:

  1. 在C++中经过30ms的时间之后退出循环的最佳方法是什么
  2. 如何在特定时间执行循环

到目前为止,我已经尝试使用一个Stopwatch对象来跟踪已用时间,但它对我不起作用.到目前为止,我尝试了两种不同的方法:

方法1.比较for循环中的经过时间:

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

for (i = 0; i < nEntries; i++) // nEntries is typically more than 500,000
{
      // Do some stuff
      ...
      ...
      ...

      if (sw.Elapsed > TimeSpan.FromMilliseconds(200))
          break;
}

sw.Stop();
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为完成if (sw.Elapsed > TimeSpan.FromMilliseconds(200))时间超过200毫秒.因此在我的情况下毫无用处.我不确定是否 TimeSpan.FromMilliseconds()通常需要这么长时间,或者仅仅因为某些原因而在我的情况下.

方法2.创建一个单独的线程来比较时间:

Stopwatch sw = new Stopwatch();
sw.Start();                    
bool bDoExit = false;
int msLimit = 200;

System.Threading.ThreadPool.QueueUserWorkItem((x) =>
{
     while (bDoExit == false)
     {
        if (sw.Elapsed.Milliseconds > msLimit)
        {
            bDoExit = true;
            sw.Stop();
         }

         System.Threading.Thread.Sleep(10);
      }

});

for (i = 0; i < nEntries; i++) // nEntries is typically more than 500,000
{
      // Do some stuff
      ...
      ...
      ...

      if (bDoExit == true)
          break;
}

sw.Stop();
Run Code Online (Sandbox Code Playgroud)

我在for循环中有一些其他代码可以打印一些统计信息.它告诉我,在方法2的情况下,for循环肯定完成所有迭代之前中断,但循环时间仍然是280-300毫秒.

有没有建议在200毫秒或更短的时间内严格打破for循环?谢谢.

Iva*_*n G 6

为了更快的比较尝试比较

if(sw.ElapsedMilliseconds > 200)
   break;
Run Code Online (Sandbox Code Playgroud)

您应该检查循环的开始以及处理期间("//做一些事情"代码的一部分),因为例如处理可以从190开始(循环开始),持续20并在210结束.

您还可以测量处理的平均执行时间(这是近似的,因为它依赖于平均时间),这种方式循环应该持续200毫秒或更短,这是一个演示,您可以放在控制台应用程序的Main方法中轻松根据您的应用修改它:

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

        string a = String.Empty;
        int i;
        decimal sum = 0, avg = 0, beginning = 0, end = 0;
        for (i = 0; i < 700000; i++) // nEntries is typically more than 500,000
        {
            beginning = sw.ElapsedMilliseconds;
            if (sw.ElapsedMilliseconds + avg > 200)
                break;

            // Some processing
            a += "x";
            int s = a.Length * 100;
            Thread.Sleep(19);
            /////////////

            end = sw.ElapsedMilliseconds;
            sum += end - beginning;
            avg = sum / (i + 1);

        }
        sw.Stop();

        Console.WriteLine(
          "avg:{0}, count:{1}, milliseconds elapsed:{2}", avg, i + 1,
          sw.ElapsedMilliseconds);
        Console.ReadKey();
Run Code Online (Sandbox Code Playgroud)