当前位置:  开发笔记 > 编程语言 > 正文

使用Thread.Sleep和Timer进行比较以延迟执行

如何解决《使用Thread.Sleep和Timer进行比较以延迟执行》经验,为你挑选了3个好方法。

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

我应该用吗?

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.你有什么建议吗?

或者如果你有延迟执行的替代代码也很感激.



1> Eric Rosenbe..:

一个区别是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是要走的路.


它也值得指出与System.Windows.Forms.Timer的区别,我相信*在UI线程上调用一个函数,这对WinForms应用程序非常重要!
出于好奇......记录在哪里?
对于未来的读者来说,"睡眠"不是保证至少保证的事件,而是记录它可能更少.

2> 小智..:

使用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);


我更喜欢RegisterWaitForSingleObject用于逻辑...该方法在时间到了时执行ON ...因此,一旦完成作业,你就不必停止计时器了...所以RegisterWaitForSingleObject自然地完成了什么他想要,当你想要在特定的时间间隔执行几次任务时,计时器不要计时器更好....

3> Shawn..:

我认为如果你真的想暂停应用程序指定的时间,Thread.Sleep就可以了.我认为人们说这是一个糟糕的设计的原因是因为在大多数情况下,人们实际上并不希望应用程序暂停.

例如,我正在使用pop3客户端,程序员使用Thread.Sleep(1000)等待套接字检索邮件.在这种情况下,最好将一个事件处理程序连接到套接字并在套接字完成后继续执行程序.


除了帖子中的任何一个示例之外,应用程序实际上都是暂停的.海报在一个单独的线程上暂停,而不是直接调用Thread.Sleep.直接调用Thread.Sleep,是的,坏主意.
推荐阅读
php
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有