更新:以下で説明する各手法のメモリへの影響をテストするプログラムを作成しました。それほど驚くことではありませんが、確かに、.NET イベントを使用する従来のアプローチは、他のアプローチよりも多くのガベージを作成することがわかりました (つまり、他の 2 つの戦略はどちらも作成しないように見えるのとは対照的に、実際にはガベージを作成します)。ゴミは一切ありません)。
実際、速度に関するコストよりも、.NET イベントの引数のメモリオーバーヘッドに関心があることを最初から強調しておくべきでした。最終的には、メモリと速度の両方の点で、すべての実用的な目的のために、コストはごくわずかであることを認めなければなりません。それでも、「従来の」方法で多くのイベントを発生させると、何らかのコストがかかること、そして極端な場合には、第 1 世代のガベージ コレクションにつながる可能性があることは興味深いと思いました。状況(私の経験では、システムがより「リアルタイム」である必要があるほど、ガベージが作成されている場所と、必要に応じてそれを最小限に抑える方法に注意することがより重要です)。TEventArgs
これはばかげた質問のように思えるかもしれません。たとえば、Windows フォームは、常に数百または数千のイベント (Control.MouseMove
イベントなど) が非常に急速に連続して発生するため、「高パフォーマンス」のシナリオと簡単に見なすことができます。しかし、クラスが高パフォーマンスでタイム クリティカルなコードで使用されることが予想される場合に、.NET イベントを使用してクラスを設計することが本当に合理的かどうか疑問に思っています。
私が持っている主な懸念は、イベントが発生/処理されるたびにインスタンス化する必要があるクラスから派生し、おそらくクラスであるEventHandler<TEventArgs>
すべてのイベントに似たようなものを使用するという規則です。(単純な場合、明らかに、これは使用できるケースではありません。ただし、意味のある非定数情報が型に含まれていると仮定すると、インスタンス化がおそらく必要になります。)高性能ライブラリが作成されることを期待しています。TEventArgs
EventArgs
EventsArgs
EventArgs.Empty
TEventArgs
とはいえ、私が考えることができる唯一の選択肢は次のとおりです。
- イベントに型にはまらないデリゲート型 (つまり、 ではない) を使用し、 、 など
EventHandler<TEventArgs>
のオブジェクトのインスタンス化を必要としないパラメーターのみを取得します( 、既存の文字列オブジェクトへの参照を渡すこともできます)。int
double
string
- イベントを完全にスキップし、仮想メソッドを使用して、必要に応じてクライアント コードを強制的にオーバーライドします。これは基本的に前のアイデアと同じ効果を持っているようですが、より制御された方法です。
.NET イベントの GC プレッシャーに関する私の懸念は、そもそも根拠のないものですか? もしそうなら、私はそこに何が欠けていますか? または、私がリストした 2 つよりも優れた 3 番目の選択肢はありますか?