C#Timer或Thread.Sleep

我正在运行一个Windows服务,并使用循环和Thread.Sleep来重复一个任务,使用计时器方法会更好吗?

如果是的话,代码示例会很好

我目前使用这个代码重复

int curMinute; int lastMinute = DateTime.Now.AddMinutes(-1).Minute; while (condition) { curMinute = DateTime.Now.Minute; if (lastMinute < curMinute) { // do your once-per-minute code here lastMinute = curMinute; } Thread.Sleep(50000); // sleeps for 50 seconds if (error condition that would break you out of this) { break; // leaves looping structure } } 
 class Program { static void Main(string[] args) { Timer timer = new Timer(new TimerCallback(TimeCallBack),null,1000,50000); Console.Read(); timer.Dispose(); } public static void TimeCallBack(object o) { curMinute = DateTime.Now.Minute; if (lastMinute < curMinute) { // do your once-per-minute code here lastMinute = curMinute; } } 

代码可能类似于上面的那个

计时器是一个更好的主意,海事组织。 这样,如果您的服务被要求停止,它可以很快地做出响应,而不是再次调用计时器滴答处理程序…如果您正在睡觉,服务经理将不得不等待50秒或者杀死线程,这两者都不是非常好。

重要的是要明白,你的代码将结束一个循环睡眠50秒,然后开始下一个…

一个计时器会每隔50秒调用一次你的循环,这是不完全一样的。

他们都是有效的,但计时器可能是你在这里寻找的。

请注意,调用Sleep()会冻结服务,因此如果服务被请求停止,它将不会在Sleep()调用期间作出反应。

是的,使用计时器将释放当前大部分时间都在睡觉的线程。 一个计时器也将更准确地每分钟开火,所以你可能不会需要跟踪lastMinute了。

不太回答这个问题,而不是回答

  if (error condition that would break you out of this) { break; // leaves looping structure } 

你应该有

 while(!error condition) 

另外,我会去Timer

我已经使用了定时器和Thread.Sleep(x),或者根据情况。

如果我有一段需要重复运行的代码,我可能使用一个计时器。

如果我有一段代码可能比延迟计时器运行时间要长(例如通过FTP从远程服务器检索文件,我不控制或知道networking延迟或文件大小/计数),我会等待循环之间的固定时间段。

两者都是有效的,但正如前面指出的那样,他们做了不同的事情 计时器每x毫秒运行一次代码,即使前一个实例还没有完成。 Thread.Sleep(x)在完成每次迭代之后等待一段时间,因此每个循环的总延迟将总是比睡眠周期更长(可能不会太多)。

我需要一个线程每分钟触发一次( 请参阅这里的问题 ),我现在已经根据我收到的答案使用了一个DispatchTimer

答案提供了一些您可能会觉得有用的参考资料。

我同意,使用计时器是最好的select。 我已经尝试过类似于你的解决scheme,并开始有问题,在循环会失火,我将不得不等待另一个Thread.Sleep()之前,它会再次触发。 此外,它确实会导致与停止服务有关的各种问题,我会得到不断的错误,如何不响应,不得不被closures。

@ Prashanth的代码应该正是你所需要的。

你可以使用任何一个。 但是,我认为Sleep()很容易,清晰,实施时间短。

我不得不说,睡眠是一个更好的实现与状态机背后。 这将使您始终保持对应用程序的控制,但允许在任何特定时间需要任何响应。 这也将处理比“循环中处理执行时间”短的定时器callback

例如..

 <!-- language: c# --> public enum State { Idle = 0, Processing = 1, Stop = 100, } public void Run() { State state = State.Idle; // could be a member variable, so a service could stop this too double intervalInSeconds = 60; System.DateTime nextExecution = System.DateTime.Now.AddSeconds(intervalInSeconds); while (state != State.Stop) { switch (state) { case State.Idle: { if (nextExecution > System.DateTime.Now) { state = State.Processing; } } break; case State.Processing: { // do your once-per-minute code here // if you want it to stop, just set it state to stop. // if this was a service, you could stop execution by setting state to stop, also // only time it would not stop is if it was waiting for the process to finish, which you can handle in other ways state = State.Idle; nextExecution = System.DateTime.Now.AddSeconds(intervalInSeconds); } break; default: break; } System.Threading.Thread.Sleep(1); } }