比较使用 Thread.Sleep 和 Timer 延迟执行 [英] Compare using Thread.Sleep and Timer for delayed execution

查看:45
本文介绍了比较使用 Thread.Sleep 和 Timer 延迟执行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个方法应该在指定的时间内延迟运行.

I have a method which should be delayed running for a specified amount of time.

我应该使用

Thread thread = new Thread(() => {
    Thread.Sleep(millisecond);
    action();
});
thread.IsBackground = true;
thread.Start();

Timer timer = new Timer(o => action(), null, millisecond, -1);

我读过一些文章 关于使用 Thread.Sleep 是糟糕的设计.但我真的不明白为什么.

I had read some articles about using Thread.Sleep is bad design. But I don't really understand why.

但是对于使用 Timer,Timer 有 dispose 方法.由于执行延迟,我不知道如何处理Timer.你有什么建议吗?

But for using Timer, Timer has dispose method. Since the execution is delayed, I don't know how to dispose Timer. Do you have any suggestions?

或者,如果您有延迟执行的替代代码,也将不胜感激.

Or if you have alternative codes for delayed execution are also appreciate.

推荐答案

一个区别是 System.Threading.Timer 在线程池线程上调度回调,而不是每次都创建一个新线程.如果您需要在应用程序的生命周期中多次发生这种情况,这将节省创建和销毁一堆线程的开销(正如您参考的文章指出的那样,这是一个非常资源密集型的过程),因为它会只需重用池中的线程,如果您将有多个计时器同时运行,则意味着您将有更少的线程同时运行(也可节省大量资源).

One difference is that System.Threading.Timer dispatches the callback on a thread pool thread, rather than creating a new thread every time. If you need this to happen more than once during the life of your application, this will save the overhead of creating and destroying a bunch of threads (a process which is very resource intensive, as the article you reference points out), since it will just reuse threads in the pool, and if you will have more than one timer going at once it means you will have fewer threads running at once (also saving considerable resources).

换句话说,Timer 会更有效率.它也可能更准确,因为 Thread.Sleep 只能保证至少等待您指定的时间(操作系统可能会让它休眠更长时间).当然,Timer 仍然不会完全准确,但目的是在尽可能接近指定时间时触发回调,而这不一定是 Thread.Sleep 的意图.

In other words, Timer is going to be much more efficient. It also may be more accurate, since Thread.Sleep is only guaranteed to wait at LEAST as long as the amount of time you specify (the OS may put it to sleep for much longer). Granted, Timer is still not going to be exactly accurate, but the intent is to fire the callback as close to the specified time as possible, whereas this is NOT necessarily the intent of Thread.Sleep.

至于销毁Timer,回调可以接受一个参数,所以你可以将Timer本身作为参数传入,在回调中调用Dispose(虽然我还没有尝试过——我猜定时器可能在回调过程中被锁定了).

As for destroying the Timer, the callback can accept a parameter, so you may be able to pass the Timer itself as the parameter and call Dispose in the callback (though I haven't tried this -- I guess it is possible that the Timer might be locked during the callback).

不,我猜你不能这样做,因为你必须在 Timer 构造函数本身中指定回调参数.

No, I guess you can't do this, since you have to specify the callback parameter in the Timer constructor itself.

也许是这样的?(再说一次,还没真正尝试过)

Maybe something like this? (Again, haven't actually tried it)

class TimerState
{
    public Timer Timer;
}

...并启动计时器:

TimerState state = new TimerState();

lock (state)
{
    state.Timer = new Timer((callbackState) => {
        action();
        lock (callbackState) { callbackState.Timer.Dispose(); }
        }, state, millisecond, -1);
}

锁定应防止计时器回调在设置 Timer 字段之前尝试释放计时器.

The locking should prevent the timer callback from trying to free the timer prior to the Timer field having been set.

附录:正如评论者指出的,如果 action() 对 UI 做了一些事情,那么使用 System.Windows.Forms.Timer 可能是更好的选择,因为它将在 UI 线程上运行回调.但是,如果情况并非如此,则归结为 Thread.SleepThreading.TimerThreading.Timer 是去吧.

Addendum: As the commenter pointed out, if action() does something with the UI, then using a System.Windows.Forms.Timer is probably a better bet, since it will run the callback on the UI thread. However, if this is not the case, and it's down to Thread.Sleep vs. Threading.Timer, Threading.Timer is the way to go.

这篇关于比较使用 Thread.Sleep 和 Timer 延迟执行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆