1

私は.NET 4でコレクションベースのプロジェクトを持っています。つまり、マスターコレクションがあり、それを「システム」と呼びます。これは、フレームで構成され、それぞれがカードで構成され、順番に作成されますチャンネルのアップ。つまり、System->Frame->Card->Channel のようになります。これらはすべてオブジェクトとして表現され、それらの間には親子関係があります。基本的に、Channel は Card にのみ公開され、Card は Frame にのみ公開され、Frame は System にのみ公開されます。

理想的には、System クラスのメソッドのみを外部に公開したいと考えています。ただし、Channel、Card、および Frame クラスで発生する重要なイベントがあります。現在、私がそれらを処理する方法は、伝播によるものです。チャネルでイベントが発生したとします。このイベントは、最初に Card で発生し、次に Frame で発生し、最後に System で発生します。これにより、大量のコードが生成されることがわかります。しかし、私の主な関心事はコードではなく、パフォーマンスです。

この伝播は私のパフォーマンスに悪影響を与えると思いますか? より効率的にする方法はありますか?他にどのようなオプションがありますか? 私のコレクションは比較的小さいです。System is 1, Frames < 16, Cards < 256, Channels < 8192. ほとんどのデータは Channel クラスに保存され、その中にプリミティブ オブジェクトしかありません。

編集

チャネルによって発生するイベントのカードにあるコードは次のとおりです。

protected virtual void OnChannelPropertyChanged(Object sender, PFPropertyChangedEventArgs e)
    {
        try
        {
            EventHandler<PFPropertyChangedEventArgs> handler = ChannelPropertyChanged;
            TestEventArgs_ChannelPropertyChanged = e;
            if (handler != null)
            {
                handler(sender, e);
            }
        }
        catch (Exception ex)
        {
            Milltown.MTCore.mtException mtEx = new Milltown.MTCore.mtException((int)PFExceptions.Exception_Hidden_FuctionLevel, ex,
            PFCommonVariables.ApplicationPlatform, PFCommonVariables.ApplicationDataSource, "PFCard:OnChannelPropertyChanged");
        }
    }

Card クラス内の Card に Channel を追加するときは、次のように呼び出します。

channel.ChannelPropertyChanged += this.OnChannelPropertyChanged;
4

2 に答える 2

3

System クラスでこれを行うことができます。

event EventHandler FrameEvent
{
    add { this.frame.FrameEvent += value; }
    remove { this.frame.FrameEvent -= value; }
}

したがって、クライアントがこれを行う場合

system.FrameEvent += Handler;

ハンドラーは、実際には Frame クラスの Event に関連付けられています。

于 2010-07-20T15:23:25.970 に答える
2

パフォーマンスに影響するかどうかを判断する唯一の方法は、テストすることです。イベントを伝播する方法を試してから、直接接続する別の方法を試してください。どちらが速いかを見てください。

そうは言っても、デリゲート呼び出しを 1 回だけではなく、数回連続して実行した場合に、パフォーマンスに大きな影響があるとは思えません。はい、デリゲートは実際のメソッドよりも呼び出しがわずかに遅いため、すべてが等しい場合、間接的なレベルを追加すると、通常のメソッド呼び出しと同じレベルよりも大きな影響がありますが、これは時期尚早の最適化の匂いがします.

あなたのアプローチは、誰かがあなたが求めていることをする方法を尋ねられた場合に私がお勧めするものです. 問題がなければ、それに従ってください。

編集

別の回答に対するあなたのコメントに応えて、私は拡大したいと思いました。C# イベントには、「プロパティ構文」と呼ばれるものがあります。クラスで明示的に実装すると、次のようになります。

private EventHandler eventDelegate;

public event EventHandler MyEvent
{
    add { eventDelegate += value; }
    remove { eventDelegate -= value; }
}

(実際には を使用していますDelegate.Combineが、ここでは重要ではありません)

イベントにアタッチすると、実際にaddコードが呼び出され、デリゲートが渡されてアタッチされvalueます。についても同様ですremove

次のような省略形のイベント構文を使用する場合:

public event EventHandler MyEvent;

実際には、私が上に投稿したものと非常によく似たコードを内部で生成します。addただし、明示的にすると、およびremoveハンドラーで好きなことを行うことができます。これは、ターゲット デリゲートを別の場所にリダイレクトできることを意味します。他の答えの場合、デリゲートを子オブジェクトにリダイレクトしています。

これは、次の条件が当てはまる場合にのみ機能します。

  1. 親と子の間には 1:1 の相関関係があり、関連するオブジェクトは変更されません
  2. 子オブジェクトへの参照の公開 ( as object) は許容されます

複数の子がいる場合は、技術的には可能ですが (ループして でそれらすべてにアタッチし、 ですべてadd削除することもできますremove)、管理するのははるかに困難です。関連するオブジェクトまたはオブジェクトのコレクションがイベントのアタッチ後に変更される可能性がある場合、調整は事実上不可能になります。

さらに、イベントがイベントの推奨プラクティス (トリガー オブジェクトを として渡すsender) に従っている場合、ターゲットを自分で発生させるのではなく、子イベントに直接アタッチしているため、への参照を公開することになります。この引数を介して子オブジェクト。それがあなたにとって適切かどうか、または受け入れられるかどうかはわかりませんが、考慮すべきことです。

于 2010-07-20T15:14:31.307 に答える