我有一个方法应该延迟指定的时间运行。
我应该使用
Thread thread = new Thread(() => {
Thread.Sleep(millisecond);
action();
});
thread.IsBackground = true;
thread.Start();
或者
Timer timer = new Timer(o => action(), null, millisecond, -1);
我读过一些articles关于如何使用 Thread.Sleep
是糟糕的设计。但我真的不明白为什么。
但是,为了使用 Timer
,Timer
有一个 dispose 方法。由于执行延迟,我不知道如何处理Timer
。你有什么建议吗?
或者,如果您有延迟代码执行的替代建议,我们也将不胜感激。
最佳答案
一个区别是 System.Threading.Timer
在线程池线程上调度回调,而不是每次都创建一个新线程。如果您需要在应用程序的生命周期中不止一次发生这种情况,这将节省创建和销毁一堆线程的开销(正如您引用的文章所指出的那样,这是一个非常耗费资源的过程),因为它会只需重用池中的线程,如果您将同时运行多个计时器,则意味着您将同时运行更少的线程(同时节省大量资源)。
换句话说,Timer
会更有效率。它也可能更准确,因为 Thread.Sleep
只能保证至少等待您指定的时间(操作系统可能会使其休眠更长时间)。诚然,Timer
仍然不会完全准确,但目的是在尽可能接近指定时间时触发回调,而这不一定是 Thread.Sleep 的目的
。
至于销毁Timer
,回调可以接受一个参数,所以你可以将Timer
本身作为参数传递,并在回调中调用Dispose(尽管我还没有尝试过这个——我猜 Timer 可能在回调期间被锁定)。
编辑:不,我猜你不能这样做,因为你必须在 Timer
构造函数本身中指定回调参数。
也许是这样的? (再一次,还没有真正尝试过)
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
字段之前尝试释放计时器。
附录:正如评论者所指出的,如果 action()
对 UI 做了一些事情,那么使用 System.Windows.Forms.Timer
可能是更好的选择,因为它将在 UI 线程上运行回调。但是,如果情况并非如此,并且取决于 Thread.Sleep
与 Threading.Timer
,则 Threading.Timer
是去吧。
关于c# - 比较使用 Thread.Sleep 和 Timer 延迟执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/391621/