40

最近何人かの開発者が、単に何か (データベース、ファイルなど) をポーリングして何かが変更されたことを判断し、インポートなどのタスクを実行していると言っているのを耳にしました。

私はこの考えに本当に反対で、RemotingWCFなどの利用可能なテクノロジを利用することは、ポーリングよりもはるかに優れていると感じています。

しかし、他の人が 1 つのアプローチを他のアプローチよりも好む理由を特定したいと思います。さらに重要なこととして、この時代に世論調査が間違っていることを他の人に納得させるにはどうすればよいでしょうか?

4

18 に答える 18

47

ポーリング自体は「間違っている」わけではありません。

多くは、実装方法と目的によって異なります。変更をすぐに通知することが本当に重要な場合は、非常に効率的です。あなたのコードはタイトループに陥り、リソースが変更/更新されたかどうかを常にポーリング (質問) しています。これは、何かが違うとすぐに通知されることを意味します。ただし、コードは他に何もしていないため、問題のオブジェクトへの呼び出しが多数あるという点でオーバーヘッドがあります。

即時の通知にあまり関心がない場合は、ポーリング間の間隔を長くすることができます。これもうまく機能しますが、正しい間隔を選択するのは難しい場合があります。長すぎると重要な変更を見逃す可能性があり、短すぎると最初の方法の問題に戻ります。

割り込みやメッセージなどの代替手段は、これらの状況でより良い妥協点を提供できます。事実上可能な限り早く変更が通知されますが、この遅延は制御できるものではなく、状態の変更をタイムリーに渡すコンポーネント自体に依存します。

ポーリングの何が「間違っている」のですか?

  • リソースを浪費する可能性があります。
  • それは制限になる可能性があります(特に、知りたい/投票したいことがたくさんある場合)。
  • それはやり過ぎかもしれません。

しかし...

  • それは本質的に間違っているわけではありません。
  • とても効果的です。
  • とてもシンプルです。
于 2008-11-26T10:59:38.020 に答える
27

この時代にポーリングを使用する例:

  • 電子メール クライアントは、新しいメッセージをポーリングします (IMAP を使用している場合でも)。
  • RSS リーダーは、フィードの変更をポーリングします。
  • 検索エンジンは、インデックスを作成したページへの変更をポーリングします。
  • StackOverflow ユーザーは、「更新」を押して、新しい質問をポーリングします ;-)
  • Bittorrent クライアントは、群れの変化についてトラッカーをポーリングします (そして、DHT を使用して相互にポーリングします)。
  • マルチコア システムでのスピンロックは、遅延が短すぎてこのコアで別のスレッドをスケジュールする時間がない場合に、コア間の最も効率的な同期になる可能性があります。

非同期通知を取得する方法がない場合もあります。たとえば、RSS をプッシュ システムに置き換えるには、サーバーはフィードを読むすべてのユーザーを認識し、それらに連絡する方法を用意する必要があります。これはメーリング リストです。まさに、RSS が避けるように設計されたものの 1 つです。したがって、私の例のほとんどはネットワーク アプリであり、これが問題になる可能性が最も高いという事実です。

また、非同期通知がある場合でも、ポーリングは十分に安価に機能する場合があります。

ローカル ファイルの場合、原則として、変更の通知がより適切なオプションである可能性があります。たとえば、ディスクを永遠に突っついている場合は、ディスクのスピンダウンを防ぐことができますが、OS がキャッシュする可能性があります。また、1 時間に 1 回しか変更されないファイルを毎秒ポーリングしている場合、マシンの処理能力の 0.001% (またはそれ以上) を不必要に占有している可能性があります。これは小さいように思えますが、ポーリングする必要があるファイルが 100,000 個ある場合はどうなるでしょうか?

ただし、実際には、どちらを行ってもオーバーヘッドは無視できる可能性が高いため、現在機能しているコードを変更することに興奮するのは困難です。最善の方法は、変更したいシステムでポーリングが引き起こす特定の問題に注意することです。何かが見つかった場合は、すべてのポーリングに対して一般的な議論をしようとするのではなく、問題を提起してください。何も見つからない場合、壊れていないものを修正することはできません...

于 2008-11-26T11:32:02.793 に答える
25

原則としてポーリングが悪いと見なされる理由は 2 つあります。

  1. それは資源の浪費です。変更が発生していないときに変更を確認する可能性が非常に高くなります。このアクションに費やされる CPU サイクル/帯域幅は変化をもたらさないため、別のことに費やされた方がよい可能性があります。

  2. ポーリングは一定間隔で行われます。これは、次に間隔が経過するまで変更が発生したことを認識できないことを意味します。

変更の通知をしたほうがよいでしょう。この方法では、発生していない変更をポーリングする必要がなく、通知を受け取るとすぐに変更を知ることができます。

于 2008-11-26T11:02:53.663 に答える
23

ポーリングは簡単に行うことができ、非常に簡単で、手続き型コードと同じくらい簡単です。ポーリングではないということは、非同期プログラミングの世界に足を踏み入れることを意味します。これは、脳死するほど簡単ではなく、時には困難になることさえあります。

そして、あらゆるシステムのすべてがそうであるように、通常は抵抗の少ない道がより一般的に取られます。そのため、非同期パターンで物事を複雑にする必要がない場合があるため、ポーリングを使用するプログラマー、さらには優れたプログラマーが常に存在します。

私は常にポーリングを回避するように努めていますが、特に非同期処理の実際の利点がそれほど大きくない場合、特にいくつかの小さなローカルデータに対して動作する場合など、とにかくポーリングを行うことがあります (もちろん、少し速くなりますが、ユーザーこのような場合、違いに気付かないでしょう)。したがって、両方の方法論の余地があります。

于 2008-11-26T11:00:46.863 に答える
8

クライアントのポーリングは、サーバーの通知ほど拡張されません。サーバーに「新しいデータはありますか?」と尋ねる何千ものクライアントを想像してみてください。5秒ごと。ここで、サーバーが新しいデータを通知するためにクライアントのリストを保持していると想像してください。サーバー通知のスケーリングが向上します。

于 2009-04-09T17:39:18.877 に答える
5

ほとんどの場合、イベントまたは割り込み駆動の状況であっても、あるレベルでポーリングが行われていることを認識する必要がありますが、ポーリングを実行する実際のコードからは分離されています。本当に、これは最も望ましい状況です...実装から自分自身を分離し、イベントに対処するだけです。ポーリングを自分で実装する必要がある場合でも、コードを記述して分離し、結果が実装とは無関係に処理されるようにします。

于 2008-11-26T12:01:16.070 に答える
3

特定の状況でポーリングを使用することがありますが(たとえば、ゲームでは、フレームごとにキーボードの状態をポーリングします)、ポーリングのみを行うループではなく、チェックとしてポーリングを実行します(リソースXが変更されましたか?はい、何かをします。そうでない場合は、他の何かを処理し、後でもう一度確認します)。ただし、一般的に言えば、非同期通知を優先してポーリングを避けます。

その理由は、何かが起こるのを待つためにリソース(CPU時間など)を費やさないためです(特に、それらのリソースがそもそもそのことをスピードアップできる場合)。ポーリングを使用する場合、私はアイドル状態で待機するのではなく、他の場所でリソースを使用するので、問題はありません(少なくとも私にとっては)。

于 2008-11-26T11:26:05.737 に答える
3

ポーリングについてのことは、それが機能するということです! 信頼性が高く、実装が簡単です。

プーリングのコストは高くなる可能性があります。1 日に変更が 2 つしかないときに毎分データベースをスキャンして変更を探すと、非常に小さな結果のために多くのリソースが消費されます。

ただし、通知テクノロジの問題は、実装がはるかに複雑であり、信頼性が低いだけでなく (これは大きな問題ですが)、いつ機能していないかを簡単に判断できないことです。

したがって、他のテクノロジーのポーリングを中止する場合は、平均的なプログラマーが使用でき、非常に信頼できるものであることを確認してください。

于 2008-11-26T11:03:48.230 に答える
3

その単純さ - ポーリングが悪い - 非効率的、リソースの浪費など。「ポーリング」が選択されていなくても、とにかく何らかのイベントを監視している何らかの形式の接続が常に存在します。

では、わざわざ追加のポーリングを行う必要はありません。

コールバックは最良のオプションです。コールバックを現在のプロセスに結び付けることに注意する必要があります。根底にあるのは、とにかく接続が維持されていることを確認するためのポーリングです。

ガールフレンドに電話をかけ続けても彼女が応答しない場合、なぜ電話をかけ続けるのですか? メッセージを残して、彼女が「かけ直す」まで待ってください ;)

于 2008-11-26T11:12:52.753 に答える
2

ファイルへの変更をポーリングしている場合は、これが発生したときに利用できるファイルシステム通知を使用する必要があることに同意します。これは現在、ほとんどのオペレーティング システムで利用できます。

データベースでは、更新/挿入をトリガーしてから、外部コードを呼び出して何かを行うことができます。ただし、インスタント アクションを必要としない場合もあります。たとえば、別のネットワーク上のデータベース A からデータベース B に 15 分以内にデータを取得するだけでよい場合があります。データベース B はデータベース A からアクセスできない可能性があるため、データベース B から、またはデータベース B の近くで実行されているスタンドアロン プログラムとしてポーリングを行うことになります。

また、ポーリングは非常に簡単にプログラムできます。多くの場合、時間の制約が短い場合に最初のステップとして実装されますが、十分に機能するため、そのまま使用されます。

于 2008-11-26T11:01:55.990 に答える
2

ここには多くの答えがありますが、最も簡単な答えはそれ自体の答えだと思います:

コールバックのインフラストラクチャを作成するよりも、(通常) ポーリング ループをコーディングする方がはるかに簡単だからです。

次に、後でボトルネックであることが判明した場合に簡単に理解して、別のものに再設計/リファクタリングできる、より単純なコードを取得します。

于 2008-11-26T18:08:02.307 に答える
1

ポーリングを避けることが良い方針であることに同意します。ただし、Robertの投稿を参照すると、非同期アプローチは読みにくく、保守が難しいことが多いため、ここで説明する問題がそれほど大きな問題ではない場合は、ポーリングの単純さがより良いアプローチになると思います。その実装に忍び寄る可能性のあるバグは言うまでもありません。

于 2008-11-26T11:15:36.867 に答える
1

すべての場合と同様に、それは異なります。私が取り組んでいる大規模な高トランザクションシステムは、現在SQLで通知を使用しています(SQL Server内にロードされたDLLは、特定のテーブルのトリガーから拡張SPによって呼び出されます。DLLは他のアプリに実行する作業があることを通知します)。

ただし、継続的に行う作業があることを実質的に保証できるため、これから離れています。したがって、複雑さを軽減し、実際に処理を少し高速化するために、アプリは作業を処理し、すぐにDBを再度ポーリングして新しい作業を探します。何もない場合は、少し間隔を置いて再試行します。

これはより速く動作するようで、はるかに簡単です。ただし、ボリュームがはるかに少ないアプリケーションの別の部分は、ポーリング間隔が非常に小さい場合を除いて、この方法を使用した速度の向上の恩恵を受けません。これにより、パフォーマンスの問題が発生します。そのため、この部分はそのままにしておきます。したがって、それが適切である場合、それは良いことですが、すべての人のニーズは異なります。

于 2008-11-26T11:30:36.977 に答える
1

これはあなたの質問に答えていません。しかし現実的には、特にプロセッサ サイクルが安価で帯域幅が広いこの「時代」では、ポーリングは実際にはいくつかのタスクに対して非常に優れたソリューションです。

利点は次のとおりです。

  • 安いです
  • 信頼性のある
  • テスト可能
  • フレキシブル
于 2008-11-26T11:01:08.313 に答える
0

プッシュとプルの相対的なメリットの概要は次のとおりです

この回答にさらに要約できればと思いますが、いくつかのことは省略しないでおくのが最善です。

于 2009-08-27T08:45:11.950 に答える
0

通常は非同期/メッセージングの方が優れているというほとんどの回答に同意します。ロバート・グールドの答えに完全に同意します。しかし、もう1点追加したいと思います。

さらに、ポーリングは一石二鳥です。ある特定のユース ケースでは、私が関わったプロジェクトでは、データベース間でメッセージ キューを使用していましたが、アプリケーション サーバーからデータベースの 1 つにポーリングしていました。アプリ サーバーから DB へのネットワークがダウンすることがあったため、ネットワークの問題をアプリに通知するためにポーリングが追加で使用されました。

最終的には、スケーラビリティを念頭に置いて、ユース ケースに最も適したものを使用してください。

于 2016-02-05T18:23:53.760 に答える
0

SQL ポーリングについて考えると、VB6 の時代には、非同期の「リッスン」の初期の化身である WithEvents キーワードを使用してレコードセットを作成できました。

個人的には、ポーリングの前にイベント駆動型の実装を使用する方法を常に探していました。次のいずれかを手動で実装しても問題が解決しない場合:

  • SQL サービス ブローカー/依存関係クラス
  • ある種のキュー技術 (RabbitMQ など)
  • UDP ブロードキャスト - 複数のノード リスナーで構築できる興味深い手法です。ただし、一部のネットワークでは常に可能であるとは限りません。

これらのいくつかは、プロジェクトのわずかな再設計が必要になる場合がありますが、企業の世界では、ポーリング サービスよりも優れた方法である可能性があります。

于 2015-07-03T10:29:58.733 に答える