c#:在循环前设置定时器,在定时器消失2分钟后打破循环

时间:2017-05-10 10:33:23

标签: c# timer

我对C#很陌生,之前从未使用过计时器。 我想在while循环中运行代码150秒。我的想法是在一个while循环之前设置一个计时器,它将在150秒后关闭。我设置了一个boolean exitFlag,默认情况下为false,当计时器关闭时,它将其设置为true。

public static System.Timers.Timer DL_stuckTimer;
static int secondleft = 150 ; 
static bool exitFlag = false;

public static void SetTimer()
{
    // Create a timer with a two second interval.
    DL_stuckTimer = new System.Timers.Timer(2000); //tick every 2 second
    // Hook up the Elapsed event for the timer. 
    DL_stuckTimer.Elapsed += DL_stuckTimerEvent;
    DL_stuckTimer.AutoReset = true;
    DL_stuckTimer.Enabled = true;
}

/*** Timer that goes off after 2.5 second and will tell the down
**/
public static void DL_stuckTimerEvent(Object myObject, EventArgs myEventArgs)
{
    if (secondleft == 0)
    {
        DL_stuckTimer.Stop();
        exitFlag = true;
    }
    secondleft -= 2;
}

SetTimer();

do{ 
    //some code here
} while (!exitFlag);

这不起作用。我究竟做错了什么。看起来计时器永远不会发生。

3 个答案:

答案 0 :(得分:1)

正如亚历山德罗所说,你可以使用秒表:

    public static void Main()
    {
        var sw = new Stopwatch();
        sw.Start();
        while(sw.ElapsedMilliseconds < 150000)
        {
            //Do stuff for 150 seconds.
            Thread.Sleep(2000); //Wait 2 seconds before the next iteration/tick.
        }
        sw.Stop(); //150 seconds is over.
    }

答案 1 :(得分:1)

让我们从实际问题开始:您似乎想要执行长进程,如果它没有&#,您希望在2分钟后终止它39;已完成。 这是Task s:

可以解决的问题
  using System.Threading;
  using System.Threading.Tasks;

  ... 

  // 2 minutes = 2 * 60 * 1000 milliseconds
  using (CancellationTokenSource cts = new CancellationTokenSource(2 * 60 * 1000)) {
    CancellationToken token = cts.Token;

    try {
      Task task = Task.Run(() => {
        //TODO: put relevant code here 
        ...

        // Cancellation is a cooperative, that's why do not forget to check the token 
        token.ThrowIfCancellationRequested(); 
        ... 
        }, 
      token);

      await task; 
    }
    catch (TaskCanceledException) {
      // Task has been cancelled due to timeout
      //TODO: put relevant code here 
    }
  }

答案 2 :(得分:0)

我会使用CancellationToken而非计时器来执行此操作。

然后你可以创建一个CancellationTokenSource,它将在指定的时间后自动取消。

在循环中,您可以选中CancellationToken.IsCancellationRequested

,而不是检查退出标记

完整的可编辑控制台应用示例如下所示:

using System;
using System.Threading;

namespace ConsoleApp1
{
    class Program
    {
        static void Main()
        {
            var cancellationSource = new CancellationTokenSource(TimeSpan.FromSeconds(150));

            Console.WriteLine("Started at time " + DateTime.Now);
            SomeMethod(cancellationSource.Token);
            Console.WriteLine("Finiehd at time " + DateTime.Now);
        }

        static void SomeMethod(CancellationToken cancellation)
        {
            do
            {
                Thread.Sleep(10); // Some code goes here.
            }
            while (!cancellation.IsCancellationRequested);
        }
    }
}

这样做的一个好处是它是基于任务的取消的工作原理,如果你想以另一种方式取消它,你可以传递其他类型的取消令牌。

您还可以更改忙碌循环,以便它只执行500ms的某些操作,但在发出取消令牌信号时仍会尽快退出循环。

为此,您可以使用CancellationToken.WaitOne()方法,如下所示:

static void SomeMethod(CancellationToken cancellation)
{
    do
    {
        // Do something every 500 ms.
    }
    while (!cancellation.WaitHandle.WaitOne(500)); // Wait up 500ms, but return immediatly if signalled.
}