轮询有什么问题?

时间:2008-11-26 10:52:21

标签: c# .net asp.net polling

我听说有一些开发人员最近说他们只是轮询东西(数据库,文件等)以确定什么时候发生了变化,然后运行任务,例如导入。

我真的反对这个想法,并认为利用RemotingWCF等可用技术比投票要好得多。

但是,我想确定为什么其他人更喜欢一种方法而不是另一种方法的原因,更重要的是,我怎样才能说服其他人在这个时代错误地进行民意调查呢?

18 个答案:

答案 0 :(得分:43)

投票并非“错误”。

很大程度上取决于它的实施方式和目的。如果您真的关心即时通知变更,那么效率非常高。您的代码处于紧密循环中,不断轮询(询问)资源是否已更改/更新。这意味着只要您有所不同,就会立即通知您。但是,您的代码没有做任何其他事情,并且在对相关对象的许多调用方面存在开销。

如果您不太关心立即通知,可以增加轮询之间的间隔,这也可以很好地工作,但选择正确的间隔可能很困难。太久了,你可能会错过重要的变化,太短暂而且你又回到了第一种方法的问题。

替代方案,例如中断或消息等,可以在这些情况下提供更好的折衷方案。您会在实际可能的情况下尽快收到通知,但这种延迟不是您控制的,取决于组件本身是否及时传递状态变化。

民意调查的“错误”是什么?

  • 这可能是资源匮乏。
  • 这可能是限制性的(特别是如果你想知道很多关于/民意调查的事情)。
  • 可能有点矫枉过正。

但是...

  • 这本身并不错。
  • 这可能非常有效。
  • 很简单。

答案 1 :(得分:24)

原则上,为什么民意调查可能被视为不良,这有两个原因。

  1. 这是浪费资源。在没有发生任何变化的情况下,您很可能会检查更改。此操作的CPU周期/带宽花费不会导致更改,因此可以更好地花在其他内容上。

  2. 轮询在一定时间间隔内完成。这意味着在下一次间隔过去之前,您不会知道发生了更改。

  3. 最好收到变更通知。这样,您就不会轮询尚未发生的更改,并且只要收到通知就会知道更改。

答案 2 :(得分:21)

在这个时代使用民意调查的例子:

  • 电子邮件客户端轮询新邮件(即使使用IMAP)。
  • RSS阅读器轮询Feed的更改。
  • 搜索引擎轮询其索引页面的更改。
  • StackOverflow用户通过点击'刷新'来轮询新问题; - )
  • Bittorrent客户通过DHT对跟踪器(以及我认为彼此)进行轮询更新。
  • 多核系统上的自旋锁可以是内核之间最有效的同步,如果延迟太短而没有时间在这个内核上调度另一个线程,那么另一个内核就会做我们正在等待的任何事情。

有时候根本没有任何方法可以获得异步通知:例如,用推送系统替换RSS,服务器必须知道读取订阅源并有办法联系它们的每个人。这是一个邮件列表 - 正是RSS旨在避免的事情之一。因此,我的大多数示例都是网络应用程序,这很可能是一个问题。

其他时候,即使存在异步通知,轮询也足够便宜。

对于本地文件,原则上更改通知可能是更好的选择。例如,你可能(可能)阻止磁盘停止,如果你永远戳它,虽然然后操作系统可能会缓存。如果你在一个每小时只改变一次的文件上每秒轮询一次,你可能会不必要地占用你机器处理能力的0.001%(或其他)。这听起来很小,但是当您需要轮询100,000个文件时会发生什么?

但实际上,无论你做什么,开销都可以忽略不计,这使得很难对改变当前有效的代码感到兴奋。最好的办法是注意轮询导致你想要改变的系统的特定问题 - 如果你发现任何问题然后提出这些问题而不是试图对所有轮询进行一般性论证。如果你找不到任何东西,那么就无法修复那些没有破坏的东西......

答案 3 :(得分:14)

轮询很容易做到,非常简单,就像任何程序代码一样简单。不进行轮询就意味着你进入了异步编程的世界,这种情况并不像脑子一样简单,有时甚至可能变得具有挑战性。

与任何系统中的所有内容一样,通常更常采用阻力较小的路径,因此总会有程序员使用轮询,甚至是优秀的程序员,因为有时不需要使用异步模式使事情复杂化。

我总是茁壮成长以避免轮询,但有时我会进行轮询,特别是当异步处理的实际收益不是那么好时,例如当对一些小的本地数据采取行动时(当然你会更快一点) ,但用户不会注意到这种情况下的差异)。所以两种方法都有空间恕我直言。

答案 4 :(得分:8)

客户端轮询不会像服务器通知那样扩展。想象一下,成千上万的客户向服务器询问“任何新数据?”每5秒钟。现在假设服务器保留一个客户列表来通知新数据。服务器通知更好地扩展

答案 5 :(得分:5)

我认为人们应该意识到,在大多数情况下,即使在事件或中断驱动的情况下,也会在某种程度上进行轮询,但是您与执行轮询的实际代码隔离开来。真的,这是最理想的情况......将自己与实现隔离开来,只是处理事件。即使您必须自己实现轮询,也要编写代码以使其孤立,并且结果将独立于实现进行处理。

答案 6 :(得分:3)

简单 - 轮询很糟糕 - 效率低下,资源浪费等等。即使没有选择“轮询”,总会有某种形式的连接,即监视某种事件。

那么为什么要加倍努力并进行额外的投票呢。

回调是最好的选择 - 只需要担心将回调与当前进程联系起来。在底层,有一个轮询正在进行,看看无论如何连接仍然存在。

如果你继续打电话/打电话给你的女朋友而她的答案永远没有答案,那么为什么要继续打电话?只需留言,等到她“回电话”;)

答案 7 :(得分:3)

我偶尔会在某些情况下使用轮询(例如,在游戏中,我会每帧轮询键盘状态),但从不在循环中只进行轮询,而是将轮询作为检查(具有资源X改变了?如果是的话,做一些事情,否则处理其他事情并稍后再检查)。一般来说,我避免轮询支持异步通知。

原因是我没有花费资源(CPU时间,等等)等待事情发生(特别是如果这些资源可以加速首先发生的事情)。在我使用轮询的情况下,我不会闲着等待,我在其他地方使用资源,所以这不是问题(对我来说,至少)。

答案 8 :(得分:2)

如果您要轮询文件的更改,那么我同意您应该使用可用的文件系统通知,这些通知现在在大多数操作系统中都可用。

在数据库中,您可以在更新/插入时触发,然后调用外部代码来执行某些操作。然而,可能只是您没有对即时操作的要求。例如,您可能只需要在15分钟内从不同网络上的数据库A到数据库B获取数据。数据库B可能无法从数据库A访问,因此您最终会从数据库B附近或作为独立程序进行轮询。

此外,轮询是一项非常简单的编程工作。它通常是在时间限制很短的情况下完成的第一步,并且因为它运行良好,它仍然存在。

答案 9 :(得分:2)

关于民意调查的事情是它有效!它可靠且易于实施。

汇集的成本可能很高 - 如果您每分钟扫描一次数据库以进行更改,而每天只有两次更改,则会消耗大量资源以获得非常小的结果。

然而,任何通知技术的问题在于它们实现起来要复杂得多,而且它们不仅不可靠,而且(这是一个很大的问题),你不能轻易告诉它们什么时候不工作。

因此,如果您对某些其他技术进行轮询,请确保普通程序员可以使用它并且非常可靠。

答案 10 :(得分:2)

我在这里看到很多答案,但我认为最简单的答案就是自己的答案:

因为(通常)编码轮询循环比编写回调的基础结构简单得多。

然后,您将获得更简单的代码,如果事后证明这是一个瓶颈,则可以很容易地理解并重新设计/重构为其他内容。

答案 11 :(得分:1)

与所有事情一样,这取决于。我正在使用的一个大型高事务系统当前使用带有SQL的通知(SQL Server中加载的DLL,由扩展的SP从某些表上的触发器调用。然后DLL通知其他应用程序有工作要做)。

然而,我们正在逐渐远离这一点,因为我们实际上可以保证不断有工作要做。因此,为了降低复杂性并实际加快速度,应用程序将处理他们的工作并立即再次轮询数据库以进行新工作。如果没有,它会在一小段时间后再试一次。

这似乎更快,更简单。但是,使用此方法提高速度的应用程序的另一部分体积要小得多 - 除非轮询间隔非常小,否则会导致性能问题。所以我们将它留给这部分。因此,在合适的情况下这是一件好事,但每个人的需求都是不同的。

答案 12 :(得分:1)

我同意避免投票是一项好政策。但是,在参考Robert's post时,我会说,在这里提到的问题并不是一个大问题的情况下,轮询的简单性可以使它成为一种更好的方法,因为异步方法通常不那么可读和更难保持,更不用说可能蔓延到其实施的错误。

答案 13 :(得分:1)

这不是回答你的问题。但实际上,特别是在处理器周期便宜且带宽较大的“日龄和时代”中,轮询实际上是一些非常好的解决方案。

好处是:

  • 便宜
  • 可靠
  • 可测试
  • 弹性

答案 14 :(得分:0)

以下是推拉的相对优点的一个很好的总结:  https://stpeter.im/index.php/2007/12/14/push-and-pull-in-application-architectures/

我希望我能够进一步总结这个答案,但有些事情最好保持完整。

答案 15 :(得分:0)

当考虑SQL轮询时,回到VB6那天你曾经能够使用WithEvents关键字创建记录集,这是async" listen"的早期化身。

我个人总是在轮询之前寻找一种使用事件驱动实现的方法。如果不能手动实施以下任何内容可能会有所帮助:

  • sql service broker / dependency class
  • 某种队列技术(RabbitMQ或类似的)
  • UDP广播 - 有趣的技术 用多个节点监听器构建。但是在某些网络作品中并不总是可行。

其中一些可能需要对您的项目进行轻微的重新设计,但在企业世界中,可能是更好的途径而不是投票服务。

答案 16 :(得分:0)

同意大多数回复,Async / Messaging通常更好。我绝对同意罗伯特古尔德的回答。但我想补充一点。

另外一点是,民意调查可以一石二鸟。在一个特定用例中,我参与的项目在数据库之间使用了消息队列,但是从应用程序服务器轮询到其中一个数据库。由于从应用服务器到数据库的网络偶尔会关闭,因此轮询还用于通知应用程序网络问题。

最后,在考虑到扩展能力的情况下,使用最有意义的内容。

答案 17 :(得分:0)

我正在使用轮询来检查文件上的更新,因为我正在具有不同OS类型的异构系统中获取有关该文件的信息,其中之一是非常古老的。如果文件位于具有不同OS的远程系统上,则Linux的通知将不起作用,因为该信息不会传输,但可以轮询。这是一个低带宽检查,因此不会造成任何伤害。