我不时地看到有人将操作延迟了几毫秒,以确保其正常工作。
类似于:
doSomethingInHtml();
timer.schedule(100); // delay for 100 milliseconds to ensure stuff was rendered
doSomethingElse();但是,尽管它现在可能起作用了,但是100要么太多了,因此没有很好的理由冻结应用程序,要么在一些意想不到的情况下太少了,渲染(在本例中)可能需要更长的时间。
我坚信我们永远不应该这样拖延--我们应该找到方法来确保无论依赖是什么,它已经完成了,而不是盲目地拖延,而是希望它完成。
有什么好的理由来拖延一段固定的时间来等待某件事情的完成,而不是实际地检查该动作是否完成?
发布于 2020-07-30 08:42:58
是。延迟完成检查前的时间。
是。因为人类看到的是~80赫兹。
是。为了节流,以100%的速度跑并不总是正确的选择。
不是的。通常有另一种方法来做上面的每一件事,在各个方面都是更好的。除非所有这些方法都要复杂得多,更有可能被错误所困扰,并且在已知目标平台时可能会过度使用,从而浪费宝贵的资源进行同步。
当然,一个新的目标平台将把大多数决策转化为bug,或者遗留的次优解决方案。
因此,选择一个一般的次优但自适应的解,或者选择特定的最优但僵化和非一般的解。欢迎来到软件工程,在那里我们交换这些。
发布于 2020-07-30 10:30:44
你的论点的核心是合理的,但你应用得太广泛了。
你说得对,无论固定数量是多少,都是任意的近似。但有时你所需要的是任意的近似。
例如,重复轮询外部资源的服务,直到满足某些条件,或无限期地轮询。最简单的实现方法是有一个循环(通常是while),它的主体中包含一个固定的延迟。没有那个延迟,您将以太快的速度轮询您的资源。
我坚信我们永远不应该这样拖延--我们应该找到方法来确保无论依赖是什么,它已经完成了,而不是盲目地拖延,而是希望它完成。
回头看看我的例子。我们等待的资源是应用程序的外部资源。如果不是通过轮询,我们如何知道它是完整的呢?但我们不想每秒钟投票数千次。因此,我们需要放慢投票速度。我们该怎么做呢?通过拖延。
你的论点的核心是合理的,但你运用得太广泛了。
通常,异步/等待将提供更好的资源何时完成的知识。然而,并不能保证等待的任务在完成后才能完全恢复。当等待的任务完成时,如果没有可用的线程,则可能需要更长的时间。
延迟,更具体地说,是休眠线程,保证在它结束后才能完全恢复,因为它从未放弃它的线程,所以它可以确保线程在它想要恢复时的可用性。在这种情况下,可能会有更好的用例。
在处理帧呈现或动画时,使用德尔塔时间通常更好,因为它能够动态地适应帧之间的时序(以及如何处理意外的更长/更短的定时)。
但是,增量时间并不是一件容易实现的事情,实现这种复杂性并不总是必要的。如果你正在制作幻灯片,图片每隔几秒钟就会改变一次,那么固定的延迟是非常合适的,因为人类不会注意到这一点。
类似于增量时间,您可以实现秒表,跟踪某个进程占用的时间,并根据它计算延迟时间,例如await Task.Delay(5000 - sw.ElapsedMilliseconds)。
但同样的问题是,通过动态计算的延迟时间,你能得到什么呢?从工程的角度来看,它更优雅,但仅仅因为一些东西更优雅并不意味着它更有用。
这个实现带来了一系列新的考虑。秒表可能没有你想要的精确性。你必须在任何地方管理秒表资源。如果所测量的任务花费的时间比您的最大延迟时间还要长呢?在你后悔采取这种不必要但更优雅的方法之前,你会遇到多少个bug?
发布于 2020-07-30 10:55:15
如果你能提前计算延迟的时间,那就没问题了。例如,如果一个窗口应该保持1秒的可见性,我想隐藏它,并且它已经可见了0.523秒,延迟0.477秒就可以了。还有其他一些情况,比如节流以避免毫无意义的工作。
如果你在“没有延迟的情况下应用程序崩溃,随着长时间的延迟它会减慢”,那么一个固定的延迟通常是一种黑客。如果您管理的延迟工作可靠,不会明显减慢进度,这是很难看的,但也可以。但是最好的方法总是:找出为什么一个操作需要延迟,如果有可能的话,等到操作可以安全地执行。穆特克斯,信号量等可能会有帮助。
如果问题出现在第三方代码中,那么检查危险情况可能很容易,而且速度很快,但如果它消失了,则不可能得到通知。您可以使用重复检查的计时器来代替固定的延迟。
https://softwareengineering.stackexchange.com/questions/413288
复制相似问题