我有一个方法应该延迟运行指定的时间.
我应该用吗?
Thread thread = new Thread(() => { Thread.Sleep(millisecond); action(); }); thread.IsBackground = true; thread.Start();
要么
Timer timer = new Timer(o => action(), null, millisecond, -1);
我读过一些关于使用的文章Thread.Sleep
是糟糕的设计.但我真的不明白为什么.
但是对于使用Timer,Timer有配置方法.由于执行延迟,我不知道如何配置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 vs. Threading.Timer,Threading.Timer是要走的路.
使用ThreadPool.RegisterWaitForSingleObject
而不是计时器:
//Wait 5 seconds then print out to console. //You can replace AutoResetEvent with a Semaphore or EventWaitHandle if you want to execute the command on those events and/or the timeout System.Threading.ThreadPool.RegisterWaitForSingleObject(new AutoResetEvent(false), (state, bTimeout) => Console.WriteLine(state), "This is my state variable", TimeSpan.FromSeconds(5), true);
我认为如果你真的想暂停应用程序指定的时间,Thread.Sleep就可以了.我认为人们说这是一个糟糕的设计的原因是因为在大多数情况下,人们实际上并不希望应用程序暂停.
例如,我正在使用pop3客户端,程序员使用Thread.Sleep(1000)等待套接字检索邮件.在这种情况下,最好将一个事件处理程序连接到套接字并在套接字完成后继续执行程序.