Timer
コンポーネントと、その使用または複数の使用例が原因で悪影響が発生する場合は、どのような影響があるのか疑問に思っています。実際には、プロジェクトで一度に使用するタイマーの数に制限を設ける必要がありますか?
2 に答える
まあ、すべてが相対的ですが、System.Windows.Forms.Timerはかなり高価なオブジェクトです。これは、基になるwinapi SetTimer()関数を機能させるために必要な非表示のウィンドウを作成することによって機能します。このウィンドウは共有されません。すべてのタイマーオブジェクトは独自のウィンドウを取得します。ウィンドウは一般に、より高価なオペレーティングシステムオブジェクトの1つです。
したがって、非常に厳しい上限は、10,000を超える有効なタイマーを持つことはできないということです。Windowsは、アプリがその数のウィンドウを作成することを許可しません。1つのデスクトップセッションで実行されるすべてのプロセスのすべてのウィンドウが共通のヒープを共有する必要があることを考えると、この制限のかなり南に留まる必要があります。つまり、多数のウィンドウを作成しても10,000クォータを下回ると、他のプロセスに悪影響を与える可能性があり、ヒープが使い果たされたときにプロセスが失敗する可能性があります。
妥当な上限は100前後だと思います。これらのタイマーのすべてに異なるTickイベントハンドラーがあると仮定すると、これは一般に追跡するための多数の可動部分です。そうでない場合は、別の方法でこれに取り組む必要があります。任意の数の間隔を測定するために必要なタイマーは1つだけです。手首に1つの時計を置いて予定を立てるのとほぼ同じ方法です。これを行うには、SortedListに期限を保存し、期限が最初のタイマーに対してのみタイマーを開始します。チェックマークが付いたら、期限が切れているリスト内のエントリを処理して繰り返します。期限を追加または削除するときは、タイマーを停止し、新しい最初の期限が来たらタイマーを再開します。
私はあなたがwinformsタイマーオブジェクトを意味すると仮定していますだから、
ドキュメントから:
タイマーは、ユーザー定義の間隔でイベントを発生させるために使用されます。このWindowsタイマーは、UIスレッドを使用して処理を実行するシングルスレッド環境向けに設計されています。ユーザーコードでUIメッセージポンプを使用でき、常に同じスレッドから操作するか、呼び出しを別のスレッドにマーシャリングする必要があります。
このタイマーを使用する場合は、Tickイベントを使用して、ポーリング操作を実行するか、指定した期間スプラッシュ画面を表示します。Enabledプロパティがtrueに設定されていて、Intervalプロパティがゼロより大きい場合は常に、Intervalプロパティの設定に基づいてTickイベントが一定の間隔で発生します。
したがって、アプリケーションにタイマーを詰め込み始めた場合は、その行を1行ずつ読むと、UIレンダリング時間のインターバルイベントをすぐに競うことになります。
例:タイマーを使用して時計を実行する時計アプリケーションがあります。1秒間隔ごとに、アプリケーションに手をレンダリングさせます。
このアプリケーションでは、ユーザーが必要な数の「アラーム」を定義できるようにします。それぞれが設定された時間にトリガーされる新しいタイマーを作成します。これらのアラームは周期的にすることもできます。つまり、x秒ごとに鳴る「アラーム」をユーザーが設定できるようにします。
ここで、ユーザーが周期的なアラームで発生する長時間実行タスク(DB、ネットワークリソースへのアクセス、PIの1500文字までの計算など)を実行しているとします。ここで、ユーザーが10個の長時間実行タスクを持っているとします。これらのタスクは順番に実行する必要があり、34秒間隔と5秒間隔で実行する必要があります。
これらのタイマーの動作は、次のことが発生するため、このアプリケーションには適切ではありません。
- 「目覚まし」の実行中、時計はレンダリングを停止します
- UIスレッドはすべてのメッセージを同期的に処理しているため、アラームは相互に実行される可能性があるため、キューに入れられますが、発生するはずのタイミングでは発生しません。
- あなたはあなたが望むことをしない応答しないUIになってしまいます。
ですから、できる限りお答えするために、私はあなたの実際の質問をすることができます。タイマーの数に必ずしも制限がある必要はありません。イベントハンドラーの処理にかかる時間を考慮して、タイマーが起動する間隔だけを指定します。
タイマーを使用して、最終的にUIスレッドに戻って変更を加える個別の処理スレッドを起動する場合は、ターゲットのパフォーマンスの上限に達するまで、制限を設定する必要はありません。マシーン。つまり、ある時点でタイマーの数が多すぎて、より多くのタイマーイベントを呼び出し、フォームのレンダリングに影響を与えるまでメッセージキューを詰まらせる可能性があります。
つまり、要するに:
負の影響:
- タイマーはUIスレッドで実行されるため、ブロックされます
- 間隔がイベントハンドラーの処理にかかる時間よりも短い場合、予期しない動作が発生する可能性があります。
実際には、ユーザーが制御しないコンポーネントと同様に、タイマーの使用を制限する必要があるのは、タイマーがユーザーエクスペリエンスに影響を及ぼし始めた場合のみです。
私が書いているときに感じたよりもはるかに少ない「ramble-y」を読むことを願っています。